码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #535 (Div. 3) F

时间:2019-01-28 01:11:51      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:str   i++   namespace   div   problem   mes   图片   col   targe   

F. MST Unification

题目传送门

  题意

 给你n个顶点,m条边;保证没有重边,其中存在多个MST(最小生成树),

 你可以修改一些边的权值,让其中有且仅有一个最小生成树,求最少操作的边数。

  思路:

 最小生成树算法的加工,我们从kruskal算法入手,kruskal就是先对边排序,

然后遍历边不断加入一些合格边来完善最小生成树

那么在这个过程中,如果边的权值一样的话,就会产生多种MST,但是这里

不能仅仅只是累计相同权值的边数,因为与合格边相同权值的边可能可以选择

多条。

所以我们可以将所有符合的边累加起来,然后减去(n-1)就是与合格边冲突的边

,也就是答案了

技术分享图片
#include<bits/stdc++.h>
using namespace std;
#define N 200005
int n,m;
struct node
{
    int u,v,w;
    bool operator <(const node &p) const{
      return w<p.w;
    }
}edge[N];
int fa[N];

int Find(int x)
{
    if(x==fa[x]) return x;
    else return fa[x]=Find(fa[x]);
}
int main()
{
   while(~scanf("%d %d",&n,&m))
   {
      for(int i=0;i<m;i++)
        scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w);
      for(int i=1;i<=n;i++) fa[i]=i;
       sort(edge,edge+m);
       int ans=0;
       int L=0;
       for(int i=0;i<m;i++)
       {
           int u=edge[i].u,v=edge[i].v;
           u=Find(u),v=Find(v);
           if(u!=v) ans++;
           if(i+1<m && edge[i].w!=edge[i+1].w)
           {
               for(int j=L;j<=i;j++)
               {
                   int u=edge[j].u,v=edge[j].v;
                   u=Find(u),v=Find(v);
                   if(u!=v) fa[u]=v;
               }
               L=i+1;
           }
       }
       printf("%d\n",ans-(n-1));
   }
}
View Code

 

Codeforces Round #535 (Div. 3) F

标签:str   i++   namespace   div   problem   mes   图片   col   targe   

原文地址:https://www.cnblogs.com/zhgyki/p/10328133.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!