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 }