• (F. MST Unification)最小生成树


    题目链接:http://codeforces.com/contest/1108/problem/F

    题目大意:给你n个点和m条边,然后让你进行一些操作使得这个图的最小生成树唯一,每次的操作是给某一条边加1,然后让你求出最小的操作数。

    具体思路: 最小生成树不唯一的话,指的是至少有两条边权相等的边,这两条边中的任意一条都能构成一个最小生成树的边。那么如何避免这种局面出现?

    如果两个边权相等的边在最小生成树上(可以互相替换),也就是说这两条边最这个最小生成树上的作用是可以相互替代的,那么我们在加边的时候首先考虑处理边权相等的边,这里处理的边还应该再筛选一下,我们需要处理的那些边是指的相互替代的边(如果不能相互替代,就说明这条边在最小生成树上是其他边不能替代的)。

    具体过程就是先把所有边按照边权进行排序,然后再去处理矛盾的边就可以了。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define inf 0x3f3f3f3f
     5 const int maxn = 2e5+100;
     6 struct node
     7 {
     8     int fr;
     9     int to;
    10     int cost;
    11 } q[maxn];
    12 bool cmp(node t1,node t2)
    13 {
    14     return t1.cost<t2.cost;
    15 }
    16 int father[maxn];
    17 int Find(int t)
    18 {
    19     return t==father[t]?t:father[t]=Find(father[t]);
    20 }
    21 int main()
    22 {
    23     int n,m,t1,t2,t3;
    24     scanf("%d %d",&n,&m);
    25     for(int i=1; i<=n; i++)
    26     {
    27         father[i]=i;
    28     }
    29     for(int i=1; i<=m;i++)
    30     {
    31         scanf("%d %d %d",&t1,&t2,&t3);
    32         q[i].fr=t1;
    33         q[i].to=t2;
    34         q[i].cost=t3;
    35     }
    36     sort(q+1,q+m+1,cmp);
    37     int ans=0;
    38     for(int i=1; i<=m; )
    39     {
    40         int j=i;
    41         int num=0;
    42         while(j<=m&&q[j].cost==q[i].cost)
    43             j++;
    44         for(int k=i; k<j; k++)
    45         {
    46             int t1=Find(q[k].fr);
    47             int t2=Find(q[k].to);
    48             if(t1!=t2)
    49             {
    50                 num++;
    51             }
    52         }
    53         for(int k=i; k<j; k++)
    54         {
    55             int t1=Find(q[k].fr);
    56             int t2=Find(q[k].to);
    57             if(t1!=t2)
    58             {
    59                 father[t1]=t2;
    60                 num--;
    61             }
    62         }
    63         i=j;
    64         ans+=num;
    65     }
    66     printf("%d
    ",ans);
    67     return 0;
    68 }
  • 相关阅读:
    点击Notification之后收起通知栏
    Visual Studio常用的快捷键
    数据库语法二之外键
    数据引擎 创建表完整语法,字段类型,约束条件
    数据库 tcp协程实现并发 回调函数
    GIL以及协程
    进程,互斥锁,生产者消费者,线程
    udp协议,进程(同步,异步)
    单例模式,网络编程之tcp协议以及粘包问题
    网络编程
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10320959.html
Copyright © 2020-2023  润新知