codeforces A. Hongcow Builds A Nation 并查集

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\n",sum - m ) ;  
61          
62     }
63     return 0 ; 
64 }

 

posted @ 2017-07-04 14:43  third2333  阅读(178)  评论(0编辑  收藏  举报