题目大意:
给定n个点和m条便构成一个无向简单图,求图中一共有几个圈。
题目种给出了圈的例子
其中左上角和右下角的7-10-16构成了圈。经过观察我们发现,如果k个点能够构成一个圈,那么每个结点的度数为2。根据这个性质,我们便有了以下的思路:
首先利用并查集将这个图分成若干个独立且联通的子图,接下来遍历子图中的所有结点,如果每个结点满足上述性质,那么我们就认为找到了一个圈。
需要注意的是,子图的结点个数不应该小于3,否咋无法构成一个圈。
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
typedef long long ll;
int fa[maxn];
map<int, int>mp;//存储结点node的度数
vector<int>res[maxn];
int findfather(int x)
{
if (fa[x] != x)
fa[x] = findfather(fa[x]);//路径压缩
return fa[x];
}
void Union(int a, int b)
{
fa[findfather(a)] = findfather(b);
}
int main()
{
int n,m;
int x, y;
int ans = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
fa[i] = i;
}
for (int i = 0; i < m; i++)
{
cin >> x >> y;
mp[x]++;
mp[y]++;
if(findfather(x)!=findfather(y))
Union(x, y);
}
for (int i = 1; i <= n; i++)
{
res[findfather(i)].push_back(i);
}
for (int i=1;i<=n;i++)
{
if (res[i].size() <=2)continue;//结点数应该大于2
int flag = 1;
for (int j=0;j<res[i].size();j++)
{
if (mp[res[i][j]] != 2)//每个点的度数应为2
{
flag = 0;
break;
}
}
if (flag == 1)
ans++;
}
cout << ans << endl;
}