•Problem Description
•某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?
•
•Input
•测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M;随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。
注意:两个城市之间可以有多条道路相通,也就是说
3 3
1 2
1 2
2 1
这种输入也是合法的
当N为0时,输入结束,该用例不被处理。
注意:两个城市之间可以有多条道路相通,也就是说
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
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int f[1001]; 6 int vis[1001][1001]; 7 int vis2[1001]; 8 int find(int x) 9 { 10 if(x!=f[x]) 11 f[x]=find(f[x]); 12 return x; 13 } 14 void unionn(int x,int y) 15 { 16 int fx=find(x); 17 int fy=find(y); 18 f[fy]=fx; 19 } 20 int dfs(int i) 21 { 22 vis2[i]=1; 23 if(i!=f[i]) 24 { 25 vis2[f[i]]=1; 26 dfs(f[i]); 27 } 28 return i; 29 } 30 31 int main() 32 { 33 int n,m; 34 while(scanf("%d",&n)) 35 { 36 37 memset(vis,0,sizeof(vis)); 38 memset(vis2,0,sizeof(vis2)); 39 int tot=0; 40 if(n==0)break; 41 scanf("%d",&m); 42 for(int i=1;i<=n;i++) 43 f[i]=i; 44 for(int i=1;i<=m;i++) 45 { 46 int x,y; 47 scanf("%d%d",&x,&y); 48 if(x==y)continue; 49 if(vis[x][y]==1||vis[y][x]==1)continue; 50 if(x>y) 51 { 52 swap(x,y); 53 } 54 unionn(x,y); 55 vis[x][y]=1; 56 vis[y][x]=1; 57 } 58 for(int i=n;i>=1;i--) 59 { 60 if(vis2[i]==0) 61 { 62 dfs(i); 63 tot++; 64 } 65 66 } 67 //cout<<endl; 68 cout<<tot-1; 69 //cout<<endl; 70 //cout<<endl; 71 } 72 73 return 0; 74 }