文章目录
Introduction
连通分量、连通分支、极大连通子图
:无向图 G的一个极大连通子图称为 G的一个连通分量(或连通分支)。
连通图
:如果无向图中任意两点都是连通的(连通分量=1),那么图被称作连通图。如果此图是有向图,则称为强连通图(注意:需要双向都有路径)
Sample
给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的。
利用并查集判断,最终如果连通分量等于1,那么该图就是一个连通图。
int component = 0;
for(int i = 1; i <= n; ++i){
if(Find(i) == i){
component++;
}
}
if(component == 1){
printf("YES\n");
}else{
printf("NO\n");
}
Source
吉林大学复试上机题
Solution
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 1000;
int father[MAXN];
int height[MAXN];
void Initial(int n){
for(int i = 0; i <= n; ++i){
father[i] = i;
height[i] = 0;
}
}
int Find(int x){
// 查找根结点
if(x != father[x]){
father[x] = Find(father[x]);
}
return father[x];
}
// 具体步骤
// 1. 判断根结点是否相同,判断find的结果
// 2. 合并根结点,矮树作为高树的子树,height相同时,合并且高度+1
void Union(int x, int y){
x = Find(x);
y = Find(y);
if(x != y){
if(height[x] < height[y]){
// 矮树作为高树的子树
father[x] = y;
}else if(height[y] < height[x]){
father[y] = x;
}else{
father[y] = x;
height[x]++; // 相等时 x作为父树
// 因为矮的树永远作为高树的子树
// 所以height增加的永远是根节点的那1个结点
}
}
return ;
}
int main(){
int n, m;
while(scanf("%d", &n) != EOF){
if(n == 0){
break;
}
scanf("%d", &m);
Initial(n);
while(m--){
int x, y;
scanf("%d %d", &x, &y);
Union(x, y);
}
int component = 0;
for(int i = 1; i <= n; ++i){
if(Find(i) == i){
component ++; // 集合数目
}
}
if(component == 1){
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}