• [暑假集训Day2T2]走廊泼水节


    给定一棵n个点的图上的最小生成树,让你把它补成完全图,使得新图的MST还是给定的MST且边权和最小,输出需要增加的边权和。

    设size[i]表示以i号为祖先的并查集的大小。

    首先按边权排序,之后在做MST的过程中,答案cnt+=(size[v]*size[u]-1)*(w+1),来解释一下这个式子,从v号集合到u号集合每两个点之间连一条边(除了MST上的这条边),因为MST必须还是原来的MST,所以边权要加1,之后将集合合并直到求出MST为止即可。

    下面给出参考代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define N 6005
     5 using namespace std;
     6 int read()
     7 {
     8     int x=0,f=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    11     return x*f;
    12 }
    13 int t,n,m,x,y,z,cnt,parent[N],size[N];
    14 struct node
    15 {
    16     int u,v,w;
    17 }f[N];
    18 bool cmp(node a,node b)
    19 {
    20     return a.w<b.w;
    21 }
    22 int find(int x)
    23 {
    24     if(parent[x]==x)return x;
    25     return parent[x]=find(parent[x]);
    26 }
    27 int main()
    28 {
    29     t=read();
    30     while(t--)
    31     {
    32         cnt=0;
    33         n=read();
    34         for(int i=1;i<n;i++)
    35         {
    36             x=read();y=read();z=read();
    37             f[i].u=x;f[i].v=y;f[i].w=z;
    38         }
    39         for(int i=1;i<=n;i++)parent[i]=i,size[i]=1;
    40         sort(f+1,f+n,cmp);
    41         for(int i=1;i<n;i++)
    42         {
    43             int u=find(f[i].u),v=find(f[i].v);
    44             parent[u]=v;
    45             cnt+=(size[u]*size[v]-1)*(f[i].w+1);
    46             size[v]+=size[u];
    47         }
    48         cout<<cnt<<endl;
    49     }
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    软工实践个人总结
    第02组 Beta版本演示
    第02组 Beta冲刺(5/5)
    第02组 Beta冲刺(4/5)
    第02组 Beta冲刺(3/5)
    第02组 Beta冲刺(2/5)
    第02组 Beta冲刺(1/5)
    第02组 Alpha事后诸葛亮
    第02组 Alpha冲刺(6/6)
    第02组 Alpha冲刺(5/6)
  • 原文地址:https://www.cnblogs.com/szmssf/p/11172450.html
Copyright © 2020-2023  润新知