E. Cyclic Components
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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⋅105, 0≤m≤2⋅105) — 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.
Examples
inputCopy
5 4
1 2
3 4
5 4
3 5
outputCopy
1
inputCopy
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
outputCopy
2
Note
In the first example only component [3,4,5] is also a cycle.
The illustration above corresponds to the second example.
题意:给你一个非联通图,问其中有多少个环
思路1:很容易发现,如果是一个环的话,每个节点的度数一定为2,所以只要使用dfs,把每个连通块放入一个数组,接下来验证每个节点是不是度数为2就可以了
#include<bits/stdc++.h>
#define LL long long
#define Max 100005
const LL mod=1e9+7;
const LL LL_MAX=9223372036854775807;
using namespace std;
vector<int> m[2*Max],b;
int n,k,vis[2*Max],ans;
bool check()
{
for(int i=0;i<b.size();i++){
if(m[b[i]].size()!=2)
return false;
}
return true;
}
void dfs(int x){
if(vis[x])
return ;
b.push_back(x);
vis[x]=1;
for(int i=0;i<m[x].size();i++){
if(!vis[m[x][i]])
dfs(m[x][i]);
}
}
int main()
{
scanf("%d%d",&n,&k);
int x,y;
for(int i=0;i<k;i++){
scanf("%d%d",&x,&y);
m[x].push_back(y);
m[y].push_back(x);
}
for(int i=1;i<=n;i++){
if(!vis[i]){
b.clear();
dfs(i);
if(check())
ans++;
}
}
printf("%d\n",ans);
return 0;
}
思路2 很显然并查集也可以解决联通块的问题
#include<bits/stdc++.h>
#define LL long long
#define Max 1000005
const LL mod=1e9+7;
const LL LL_MAX=9223372036854775807;
using namespace std;
int n,k,ans;
int pre[2*Max];
vector<int>m[2*Max],c[2*Max];
bool check(int n)
{
for(int i=0;i<c[n].size();i++)
if(m[c[n][i]].size()!=2)
return false;
}
return true;
}
void creat()
{
for(int i=0; i<=n; i++)
pre[i]=i;
}
int Find(int x)
{
return x==pre[x]?x:pre[x]=Find(pre[x]);
}
void Union(int x,int y)
{
pre[Find(x)]=Find(y);
}
int main()
{
scanf("%d%d",&n,&k);
int x,y;
creat();
for(int i=0; i<k; i++)
{
scanf("%d%d",&x,&y);
m[x].push_back(y);
m[y].push_back(x);
Union(x,y);
}
for(int i=1;i<=n;i++){
c[Find(i)].push_back(i);
}
for(int i=1;i<=n;i++){
if(c[i].size()>2)
if(check(i))
ans++;
}
printf("%d\n",ans);
return 0;
}