zoukankan      html  css  js  c++  java
  • Codeforces Round #535 (Div. 3) F

    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
    ",ans-(n-1));
       }
    }
    View Code
  • 相关阅读:
    私有 composer 包创建
    随机数是如何生成的
    TCP 三次握手的意义
    何为真何为假
    Python流程控制语句详解
    Python类中装饰器classmethod,staticmethod,property,
    函数进阶
    初识函数
    文件操作
    is ==小数据池编码解码
  • 原文地址:https://www.cnblogs.com/zhgyki/p/10328133.html
Copyright © 2011-2022 走看看