问题链接:https://vjudge.net/contest/274223#problem/F
问题简述:
输入城镇数与道路总数,并给出每条道路可连接的两个城镇编号,求出要使所有城镇间互相连通还需建多少条道路。
问题分析:
已连通的城镇可并为一个子集,每两个子集合并得一个子集的同时所需建的道路减少一条,可知需用到并查集算法。
程序说明:
程序先定义了变量cnt,并将其初始化为 n-1 ,表示尚无道路时需要建 n-1 条道路。定义了三个函数,init函数用于初始化所有城镇的根节点,find函数用于寻找城镇的根节点。unions函数用于合并两个子集并计数。
AC通过的C++语言程序如下:
#include<iostream>
using namespace std;
int root[1005]={0};
int cnt;
void init(int root[],int n)
{
for(int i=1;i<=n;i++)
{
root[i]=i;
}
cnt=n-1;
}
int find(int a)
{
if(root[a]==a)
return a;
else
return root[a]=find(root[a]);
}
void unions(int a,int b)
{
int i=find(a);
int j=find(b);
if(i==j)
return;
else
root[i]=j;
cnt--;
}
int main()
{
int n;
while(cin>>n)
{
if(!n)
break;
init(root,n);
int m,a,b;
cin>>m;
for(int i=0;i<m;i++)
{
cin>>a>>b;
unions(a,b);
}
cout<<cnt<<endl;
}
}