畅通工程HDU1232(并查集)

http://acm.hdu.edu.cn/showproblem.php?pid=1232

有n个城市,现在已经有了k条路,求最少还要多少条路可以让他们全部链接起来

算法核心:并查集,吧可以连通的连在一起,最后求共有几个大块

先做预处理P[i]=i;然后就是

 1 int find(int x)
 2 {
 3     return x==p[x]?x:find(p[x]);
 4 }
 5 void merg(int x,int y)
 6 {
 7     int a=find(x);
 8     int b=find(y);
 9     if(a!=b)
10     {
11         p[a]=b;
12     }
13 }

 

经过这个运算后,样例1就变成了

     3              2

  /     \

1        4

也就是p[1]=3;p[4]=3; p[1]=1;p[2]=2;

就被分成了两个部分,也就是说需要一条路

附代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define max(a,b) (a)>(b)?(a):(b)
 4 #define min(a,b) (a)<(b)?(a):(b)
 5 
 6 int p[1005];
 7 int n,k;
 8 int find(int x)
 9 {
10     return x==p[x]?x:find(p[x]);
11 }
12 void merg(int x,int y)
13 {
14     int a=find(x);
15     int b=find(y);
16     if(a!=b)
17     {
18         p[max(a,b)]=min(a,b);
19     }
20 }
21 int main()
22 {
23     while(~scanf("%d",&n) && n)
24     {
25         int i;
26         for(i=1;i<=n;i++)
27         {
28             p[i]=i;
29         }
30         scanf("%d",&k);
31         int a,b;
32         while(k--)
33         {
34             scanf("%d%d",&a,&b);
35             merg(a,b);
36         }
37         int count=-1;
38         for(i=1;i<=n;i++)
39         {
40             if(p[i]==i)count++;
41         }
42         printf("%d\n",count);
43     }
44     return 0;
45 }

 

posted @ 2013-05-27 16:32  再见~雨泉  阅读(146)  评论(0编辑  收藏  举报