题意:不解释
思路:并查集最基本的应用,m个城市需要建造m-1条道路,如果不连通(根节点不相同)那么就合并,就少建一条道路。
#include<iostream>
using namespace std;
int pre[1005];
int find(int x)//非递归的查集
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int j=x;
while(j!=r)
{
j=pre[j];
pre[j]=r;
}
return r;
}
int main()
{
int m,n,p,q,r1,r2,total;
while(scanf("%d",&m)!=EOF&&m)
{
for(int i=1;i<=m;i++)
pre[i]=i;
scanf("%d",&n);
total=m-1;//m个城镇需要建造m-1条道路
for(int i=1;i<=n;i++)
{
scanf("%d %d",&p,&q);
r1=find(p);//这里是并集
r2=find(q);
if(r1!=r2)
{
pre[r1]=r2;
total--;//如果合并 那么需要建造的道路数就减一
}
}
printf("%d\n",total);
}
return 0;
}
#include<iostream>
using namespace std;
struct node {
int parent;
}p[1010];
int m;
void make_set(int N) {
for (int i = 1 ; i <= N ; i++)
p[i].parent = i;
}
int find_set(int x) {
return (p[x].parent == x )? x : (p[x].parent = find_set(p[x].parent));
}
void join_set(int x,int y) {
int r1 , r2;
r1 = find_set(x);
r2 = find_set(y);
if(r1 != r2) {
p[r1].parent = r2;
m--;
}
}
int main() {
int N , M;
while (scanf("%d%d",&N,&M)!=EOF && N) {
make_set(N);
int a , b;
m = N - 1;
while (M --) {
scanf("%d%d",&a,&b);
join_set(a , b);
}
printf("%d\n",m);
}
}