HDU - 1232 畅通工程

 

Problem Description
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路? 
 

 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。 
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。 
 

 

Output
对每个测试用例,在1行里输出最少还需要建设的道路数目。 
 

 

Sample Input
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
 

 

Sample Output
1
0
2
998
 
一道经典的并查集模板题
AC代码如下:(仅供参考)
 
 1 #include<stdio.h>
 2 int p[1000]; //用于描述没个数的上一级,保存当前坐标的上一级,上司
 3 int find(int x)//用于查找 x 的老大,掌门人
 4 {
 5     int r=x,t,i,j; 
 6     while(p[r]!=r) //最后r即使x的老大
 7         r=p[r];
 8     t=x;
 9     while(p[t]!=r) //这是利用已知的老大的坐标,压缩路径,将老大所有的手下的的手下的手下.....全部归到只是老大的下一级,为了方便各个小弟查询老大
10     {
11         i=p[t];
12         p[t]=r;
13         t=i;
14     }
15     return r;//返回老大的坐标
16 }
17 
18 
19 int he(int x,int y)//用于将两个集合合并在一起
20 {
21     if(find(x)!=find(y))//查询两个数的老大,如果不同老大,将x的老大变成y的老大
22     {
23         p[find(y)]=p[find(x)];
24         return 1; //返回1用于题目计算需要建的路(打架的次数)
25     }
26     return 0;
27 }
28 
29 int main()
30 {
31     int n,m,x,y,i;
32     while(~scanf("%d%d",&n,&m)&&n)
33     {
34         int s=n-1;//开始若有n个点,则需要修建n-1条路(打n-1次架)
35         for(i=1;i<=n;i++)//初始化,把所有点都初始化成自己是自己的老大,自成一派
36             p[i]=i;
37         for(i=1;i<=m;i++)
38         {
39             scanf("%d%d",&x,&y);
40             if(he(x,y)==1)s--;//返回1 则表示两个不同小弟是不同的老大,打了一架后,则需要打s-1次架。
41         }
42         /*
43             计算s还可以用,此时每个门派(集合)都归纳好了,开始看看有多少个不同的集合,即看看有多少个不同的老大,根据有多少个老大,这是
44             在开始看看要打多少次架(帮派间的斗争!!)有n个老大就要打n-1次架 (有n个集合就要n-1次修路)
45             可以用一个数组存储根,在查询有多少个根!
46                 
47         */
48         printf("%d\n",s);
49     }
50 }
View Code

 

 自己敲一遍

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 
 6 int p[1100];
 7 
 8 int Find(int x)
 9 { 
10     int r = x, t, i;
11 
12     while(p[r] != r)
13         r = p[r];
14 
15     t = x;
16 
17     while(p[t] != r)
18     {
19         i = p[t];
20         p[t] = r;
21         t = i;
22     }
23 
24     return r;
25 }
26 
27 int  QQ(int x, int y)
28 {
29     if (Find(x) != Find(y))
30     {
31         p[Find(y)] = p[Find(x)];
32         return 1;
33     }
34     return 0;
35 }
36 
37 int main()
38 {
39     int n;
40 
41     while (scanf ("%d", &n), n != 0)
42     {
43         int i, m, num = n-1;
44 
45         for (i = 1; i <= n; i++)
46             p[i] = i;
47 
48         scanf ("%d", &m);
49 
50         int x, y;
51 
52         for (i = 0; i < m ;i++)
53         {
54             scanf ("%d %d", &x, &y);
55                 if (QQ(x, y) == 1)
56                 num--;
57 
58         }
59         printf ("%d\n", num);
60     }
61     return 0;
62 }
 
View Code

 

posted @ 2016-08-08 16:25  劉小佳  阅读(162)  评论(0编辑  收藏  举报