Description
在无向图G中,如果任两结点可达,则称图G是连通的; 如果G的子图G’是连通的,没有包含G’的更大子图G’’是联通的,则称G’是G的连通分图。一个无向图,要么是一个连通
图,要么是由若干个连通分图组成。形象地说,一个无向图的连通分图就是图的一个独立的部分。
由于无向图可能是不连通的,你要做的就是添加最少的边,使无向图成为一个连通图。Input
顶点数N,N个顶点的编号为1,2,3,……,N(N<= 1000)
边数M (M <= 100000)接下来有M行,每行两个整数s,t,表示从s到t有边。
Output
输出一行,一个整数cnt,表示要添加最少的边的个数
Sample Input
Original Transformed
3 2
1 21 3
3 44 4
Sample Output
Original Transformed
1
分析:简单的并查集。通过合并,将所有可以连通的点连通,再计算有多少个互不连通的图,即可知道还需多少边。
#include<cstdio>
using namespace std;
const int maxn = 1010;
int p[maxn];//存放父亲节点
int n, m;
int Find(int x){
return p[x] == x ? x : p[x] = Find(p[x]);//寻找根节点
}
void Union(int x, int y){
int x_root = Find(x);
int y_root = Find(y);
if(x_root != y_root){//如果不是连通的
p[x_root] = y_root;
n--;//连通它,并且剩下未连通的点减少一个(所需边也减少一个)
}
}
int main(){
int a, b;
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) p[i] = i;//默认每个点的父亲节点就是它本身
n--;//因为n个点只需n-1条边连接
for(int i = 0; i < m; i++){
scanf("%d%d", &a, &b);
Union(a, b);//合并
}
printf("%d\n", n);//输出此时剩下未连通的点的个数(已减一),即至少所需边的数目
return 0;
}