问题:
n 个 顶点, 给出 m 条边,问 这个图中最多有几个环。(n < 1000,m<10000)
Sample Input
8 10
0 1
1 2
1 3
2 4
3 4
0 5
5 6
6 7
3 6
4 7
Sample Output
3
分析:
并查集的简单变形应用,当 Union(v1,v2) 时,如果这两个顶点的父节点不相同,那么一定不能构成环。
相反,如果 v1,v2的父节点相同,那么一定能构成一个环,
问题的关键就是Union函数。
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAXN = 1005;
int f[MAXN];
// 声明函数
int Find(int x);
int Union(int a,int b);
void Init(int vertex,int edge);
//主函数
int main()
{
int n,m;
int sum;
while(scanf("%d %d",&n,&m) != EOF)
{
sum = 0;
Init(n,m);
int v1,v2;
for(int i = 0;i < m;i ++)
{
cin>>v1>>v2;
sum += Union(v1,v2);
}
cout<<sum<<endl;
}
return 0;
}
// initial
void Init(int vertex,int edge)
{
for(int i = 0; i < vertex; i ++)
f[i] = i;
}
// 路径压缩查找父节点
int Find(int x)
{
return x == f[x]?x:f[x] = Find(f[x]);
}
// 合并函数
int Union(int a,int b)
{
int fa = Find(a);
int fb = Find(b);
if(fa != fb)
{
f[fa] = fb;
return 0;
}
//如果根节点一样,就能形成一个环
return 1;
}