HDU-1232-畅通工程

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1232

 

 

/*

程序分析:

  给你一些城市、城市之间的某些路,让你求最少还要再建多少条路才能实现城市与城市之间两两相通。

需要注意的是,两个城市之间可以有多条路,多条也当它一条处理。如果城市之间都没有路,需要建的路

就是城市的个数减一。

解决方法:

  利用并查集的特性,把城市之间有路的合并为一个城市,最后判定有几个城市或者有几棵树就可以了。

结果也就是城市(树)数目减一,比如有三个城市就要有2条路来让他们互通! 具体看代码吧

*/

 

 

 

 

 

View Code
 1 #include<iostream>
 2 using namespace std;
 3 const int Max = 1000+10;
 4 int far[Max];
 5 int sign[Max];
 6 int rank[Max];
 7 int map[Max][Max];
 8 
 9 void make_set(int n)
10 {
11     for(int i=0; i<=n; i++)
12     {
13         far[i] = i;
14         rank[i] = 0;
15     }
16 }
17 
18 int find_2(int x)
19 {
20     int i=0;
21     while(far[x] != x)
22     {
23         sign[i++] = x;
24         x = far[x];
25     }
26     while(i--)
27     {
28         far[sign[i]] = x;
29     }
30     return x;
31 }
32 
33 
34 int find(int x)
35 {
36     if(far[x] != x)
37         return far[x] = find(far[x]);
38     return far[x];
39 }
40 
41 void uni(int a, int b)
42 {
43     a = find(a);
44     b = find(b);
45     if(a == b)
46         return;
47     if(rank[a] < rank[b])
48         far[a] = b;
49     else if(rank[a] > rank[b])
50         far[b] = a;
51     else 
52     {
53         far[a] = b;
54         rank[b]++;
55     }
56 }
57 
58 int main()
59 {
60     int n, m;
61     int a, b;
62     while(cin>>n>>m && n)
63     {
64         make_set(n);  //初始化
65 
66         if(m==0)
67         {
68             cout<<n-1<<endl;
69             continue;
70         }
71         for(int i=0; i<m; i++)
72         {
73             scanf("%d%d", &a, &b);
74             uni(a, b);
75         }
76         int ans=0;
77         for(int j=1; j<=n; j++)
78         {
79             if(find(j)  == j)
80                 ans ++;
81         }
82         cout<<ans-1<<endl;
83     }
84     
85     return 0;
86 }

 

 

View Code
 1 #include<iostream>
 2 using namespace std;
 3 #define max 50001
 4 
 5 int p[max];
 6 bool k[max];
 7 
 8 int find(int pos)
 9 {
10     if(p[pos]==-1)return pos;
11     return p[pos]=find(p[pos]);
12 }
13 int uni(int x,int y)
14 {
15     int a=find(x);
16     int b=find(y);
17     if(a==b)return 0;
18     p[a]=b;
19     return 1;
20 }
21 
22 int main()
23 {
24     int temp;
25     int a,b;
26     int n,m;
27     while(cin>>n&&n&&cin>>m)
28     {
29         //初始化
30         for(int i=1;i<=n;i++)
31         {
32             p[i]=-1;
33             k[i]=0;
34         }
35         //输入  合并
36         for(int i=1;i<=m;i++)
37         {
38             cin>>a>>b;
39             uni(a,b);
40         }
41         //标记
42         for(int i=1;i<=n;i++)
43         {
44             temp=find(i);
45             k[temp]=1;
46         }
47         //统计
48         int add=0;
49         for(int i=1;i<=n;i++)
50         {
51             if(k[i]==1)
52                 add++;
53         }
54         printf("%d\n",add-1);
55     }
56     return 0;
57 }

 

posted @ 2012-08-25 19:20  另Ⅰ中Feel▂  阅读(179)  评论(0编辑  收藏  举报