E - 畅通工程
Posted 山杉三
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了E - 畅通工程相关的知识,希望对你有一定的参考价值。
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?
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
Huge input, scanf is recommended.
Hint
Hint
解法:
这是一道应用并查集的题目,可以当作初步学习并查集思想的题目
关于并查集可以看一下这个博客 http://blog.csdn.net/dellaserss/article/details/7724401/
1 #include<iostream>
2 using namespace std;
3
4 int pre[1050];
5 bool t[1050]; //t 用于标记独立块的根结点
6
7 int Find(int x)
8 {
9 int r=x;
10 while(r!=pre[r])
11 r=pre[r];
12
13 int i=x,j;
14 while(pre[i]!=r)
15 {
16 j=pre[i];
17 pre[i]=r;
18 i=j;
19 }
20 return r;
21 }
22
23 void mix(int x,int y)
24 {
25 int fx=Find(x),fy=Find(y);
26 if(fx!=fy)
27 {
28 pre[fy]=fx;
29 }
30 }
31
32 int main()
33 {
34 int N,M,a,b,i,j,ans;
35 while(scanf("%d%d",&N,&M)&&N)
36 {
37 for(i=1;i<=N;i++) //初始化
38 pre[i]=i;
39
40 for(i=1;i<=M;i++) //吸收并整理数据
41 {
42 scanf("%d%d",&a,&b);
43 mix(a,b);
44 }
45
46
47 memset(t,0,sizeof(t));
48 for(i=1;i<=N;i++) //标记根结点
49 {
50 t[Find(i)]=1;
51 }
52 for(ans=0,i=1;i<=N;i++)
53 if(t[i])
54 ans++;
55
56 printf("%d\n",ans-1);
57
58 }
59 return 0;
60 }//dellaserss
解法2:下面的这个代码是我第一次写这道题时,自己瞎几把乱搞AC的代码,实际思路和并查集的思想很像,只是用了一种很麻烦的办法去实现
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 5 const int MAX = 1000 +500; 6 int Map[MAX][MAX],visit[MAX]; 7 int N,n; 8 9 int main() 10 { 11 while(cin>>N) 12 { 13 memset(Map,0,sizeof(Map)); 14 memset(visit,0,sizeof(visit)); 15 if(N == 0) 16 break; 17 cin>>n; 18 for(int i=1;i<=n;i++) 19 { 20 int x,y; 21 cin>>x>>y; 22 if(Map[x][y]!=1) 23 { 24 25 Map[x][y] = 1; 26 } 27 } 28 29 30 31 32 int Ti = N; 33 int ti = 0; 34 for(int i = 1;i<=N;i++) 35 { 36 for(int j = 1;j<=N;j++) 37 { 38 if(i == j) continue; 39 if(Map[i][j]==1) 40 { 41 if(visit[i]==0&&visit[j]==0) 42 { 43 ti++; 44 visit[i] = ti; 45 visit[j] = ti; 46 Ti--; 47 } 48 else if(visit[i]!=0&&visit[j]==0) 49 { 50 visit[j] = visit[i]; 51 Ti--; 52 } 53 else if(visit[j]!=0&&visit[i]==0) 54 { 55 visit[i] = visit[j]; 56 Ti--; 57 } 58 else if(visit[j]!=0&&visit[i]!=0&&visit[i]!=visit[j]) 59 { 60 int min1 = visit[i] <visit[j]?visit[i]:visit[j]; 61 int max1 = visit[i] >visit[j]?visit[i]:visit[j]; 62 Ti--; 63 for(int l = 1;l<=N;l++) 64 if(visit[l]==max1) 65 visit[l] = min1; 66 } 67 } 68 } 69 } 70 71 72 73 if(Ti==1) 74 cout<<0<<endl; 75 else 76 cout<<Ti-1<<endl; 77 78 } 79 80 81 return 0; 82 }
以上是关于E - 畅通工程的主要内容,如果未能解决你的问题,请参考以下文章