Cyclic Components (并查集)

Description

You are given an undirected graph consisting of n vertices and m edges. Your task is to find the number of connected components which are cycles.

Here are some definitions of graph theory.

An undirected graph consists of two sets: set of nodes (called vertices) and set of edges. Each edge connects a pair of vertices. All edges are bidirectional (i.e. if a vertex a is connected with a vertex b, a vertex b is also connected with a vertex a). An edge can't connect vertex with itself, there is at most one edge between a pair of vertices.

Two vertices u and v belong to the same connected component if and only if there is at least one path along edges connecting u and v.

A connected component is a cycle if and only if its vertices can be reordered in such a way that:

  • the first vertex is connected with the second vertex by an edge,
  • the second vertex is connected with the third vertex by an edge,
  • ...
  • the last vertex is connected with the first vertex by an edge,
  • all the described edges of a cycle are distinct.

A cycle doesn't contain any other edges except described above. By definition any cycle contains three or more vertices.

There are 6 connected components, 2 of them are cycles: [7,10,16] and [5,11,9,15].

Input

The first line contains two integer numbers n and m (1≤n≤$2⋅10^5$, 0≤m≤$2⋅10^5$) — number of vertices and edges.
The following m lines contains edges: edge i is given as a pair of vertices vi, ui (1≤vi,ui≤n, ui≠vi). There is no multiple edges in the given graph, i.e. for each pair (vi,ui) there no other pairs (vi,ui) and (ui,vi) in the list of edges.

Output

Print one integer — the number of connected components which are also cycles.

Input

5 4
1 2
3 4
5 4
3 5

Output

1

Input

17 15
1 8
1 12
5 11
11 9
9 15
15 5
4 13
3 13
4 3
10 16
7 10
16 7
14 3
14 4
17 6

Output

2

Note

In the first example only component [3,4,5] is also a cycle.

The illustration above corresponds to the second example.

解题思路:并查集的运用。判断单环的条件为判断每个集合(连通分量,同一个祖先节点)中所有点的度数是否都为2,并且该集合中元素的个数至少为3个,满足这两个条件才可构成单环。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=200005;
 4 int n,m,a,b,c,cnt,fa[maxn],Deg[maxn];vector<int> vec[maxn];
 5 void init(){//初始化
 6     for(int i=1;i<=n;++i)fa[i]=i;
 7 }
 8 int findt(int x){
 9     int per=x,tmp;
10     while(fa[per]!=per)per=fa[per];
11     while(x!=per){tmp=fa[x];fa[x]=per;x=tmp;}//路径压缩
12     return x;
13 }
14 void unite(int x,int y){
15     x=findt(x),y=findt(y);
16     if(x!=y)fa[x]=y;
17 }
18 int main(){
19     cin>>n>>m;
20     init();cnt=0;
21     memset(Deg,0,sizeof(Deg));
22     for(int i=1;i<=n;++i)vec[i].clear();//清空
23     while(m--){
24         cin>>a>>b;
25         unite(a,b);
26         Deg[a]++;Deg[b]++;//每个顶点的度数加1
27     }
28     for(int i=1;i<=n;++i)//把同一个祖先所有的节点放在一个邻接表中
29         vec[findt(i)].push_back(i);
30     for(int i=1;i<=n;++i){
31         if(vec[i].size()>2){//构成单环的点的个数至少为3个
32             bool flag=false;
33             for(size_t j=0;j<vec[i].size();++j)
34                 if(Deg[vec[i][j]]!=2){flag=true;break;}//如果度数不为2的,直接退出
35             if(!flag)cnt++;//如果是单环,计数器就加1
36         }
37     }
38     cout<<cnt<<endl;
39     return 0;
40 }
原文地址:https://www.cnblogs.com/acgoto/p/9313348.html