codeforces A. Hongcow Builds A Nation
并查集
题意 给定一张无向图
其中 有 k 个特殊点
特殊点之间不能存在 路径求 最多能加多少边
不能有重边自环
将各个连通块在没有加边的时候的点数 算出来
然后 将自由的点 都加入 到 点数最多的连通块中,
然后算出加边以后的总边数
减去原有的边数就是答案了
1 #include <bits/stdc++.h> 2 using namespace std ; 3 4 const int N = 1011 ; 5 struct node{ 6 int n,number,flag ; 7 }fa[N]; 8 int n,m,k,sum,id ; 9 bool vis[N] ; 10 11 12 inline int find(int x) 13 { 14 if(fa[ x ].n ==x ) return x ; 15 return fa[ x ].n = find(fa[ x ].n) ; 16 } 17 18 inline void Union(int x,int y) 19 { 20 int fx = find(x) ; 21 int fy = find(y) ; 22 if(fx==fy) return ; 23 if(vis[fy]) swap(fx,fy) ; 24 25 if(vis[fx]) 26 fa[ fx ].number+=fa[ fy ].number ,fa[ fy ].n = fx ; 27 else 28 fa[ fy ].number+=fa[ fx ].number ,fa[ fx ].n = fy ; 29 } 30 31 int main() 32 { 33 while(~scanf("%d%d%d",&n,&m,&k)) 34 { 35 for(int i=1;i<N;i++) vis[ i ] = 0 ; 36 int x,y ; 37 for(int i=1;i<=n;i++) 38 fa[ i ].n = i ,fa[ i ].number = 1 ,fa[ i ].flag = 0 ; 39 40 for(int i=1;i<=k;i++) 41 { 42 scanf("%d",&id) ; 43 vis[id] = 1 ; 44 } 45 46 for(int i=1;i<=m;i++) 47 { 48 scanf("%d%d",&x,&y) ; 49 Union(x,y) ; 50 } 51 52 for(int i=1;i<=n;i++) 53 if( vis[ i ] && fa[ i ].number > fa[ id ].number ) id = i ; 54 for(int i=1;i<=n;i++) 55 if( !vis[ i ] && fa[ i ].n==i ) Union( id,i ) ; 56 sum = 0 ; 57 for(int i=1;i<=n;i++) 58 if(vis[ i ] || fa[ i ].n==i) 59 sum+=(fa[ i ].number-1) * fa[ i ].number /2 ; 60 printf("%d ",sum - m ) ; 61 62 } 63 return 0 ; 64 }