这是一个比较简单的并查集题目。我们把每一片城区看做一个集合(图的一个连通集),然后统计一共有k个集合,连接两个集合需要1条边,从而整个需要 k-1条边。
#include<iostream>
using namespace std;
#define MAX_SIZE 1000
int parent[MAX_SIZE];
int findParent(int i);
void Union(int i, int j);
int main(){
int i, j,k, n, e,ans;
while (scanf("%d",&n)&&n){
scanf("%d",&e);
memset(parent, -1, sizeof(parent));
for (k = 0; k < e; k++){
scanf("%d%d",&i,&j);
Union(i, j); //合并i与j所在的集合
}
ans = 0;
for (i = 1; i <= n;i++) //统计有多少个集合(连通集)
if (parent[i] ==-1)
ans++;
printf("%d\n", ans-1);
}
return 0;
}
int findParent(int i){
if (parent[i] == -1)
return i;
else
return parent[i] = findParent(parent[i]); //状态压缩
}
void Union(int i, int j){
i = findParent(i);
j = findParent(j);
if (i!=j) //如果不在同一集合就合并它们,这步不能省
parent[i] = j;
}