题意:
某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少还需要建设多少条道路?
思路:
相当于给你一个有好几个点的图,让你求算连通分支数,如果连通分支数为1,则说明整个图是一个整体不需要修路,即修(1-1)条;如果连通分支数为2,则需要一条路,把两个分支连起来,试图成为一个完整连通,即修(2-1)条路;如果连通分支数为3,则需要两条路,把两个分支连起来,试图成为一个完整连通,即修(3-1)条路……如果连通分支数为n,则需要n-1条路,把两个分支连起来,试图成为一个完整连通,即修(n-1)条路。所以本题转化为求连通分支数,然后减1即所求。利用并查集只需要求根是自身的点的个数即可。
//也可以初始要修的路数为(n-1),然后有一个在输入的所有连通的点,如果两个点原本不连通,则将其连通,所修路数减1;即在下面加感叹号的地方 加一句(ans++)即如下:
if(x!=y) {ans++; pre[x]=y;}
AC代码:
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
int pre[10001];
int n,m;
void chushi()
{
for(int i=0;i<n;i++)
{
pre[i]=i;
}
}
int root(int x)
{
if(x!=pre[x])
pre[x]=root(pre[x]);
return pre[x];
}
int main()
{
int a,b;int ans=-1;
while(scanf("%d",&n)&&n)
{
memset(pre,0,sizeof(pre));
ans=-1;
scanf("%d",&m);
if(m==0)
{
cout<<n-1<<endl;
continue;
}
chushi();
for(int i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
int x=root(a);
int y=root(b);
if(x!=y) !!!
pre[x]=y;
}
for(int i=0;i<n;i++)
{
if(pre[i]==i)//计算一共几条独立的城市
ans++;
}
cout<<ans<<endl;
}
}