Circle Detect
Description
You are given a directed graph G which has N nodes and M directed edges. Your task is to detect whether it contains any circle.
Input
The first line contains an integer T denoting the number of test cases. (1 <= T <= 5)
For each test case the first line contains two integers N and M. (1 <= N, M <= 100000)
Then follows M lines. Each contains two integers u and v denoting there is an edge from u to v. (1 <= u, v <= N)
Output
For each test case output “YES” or “NO” denoting whether there is a circle in the graph.
Sample Intput
2
5 5
1 2
2 3
4 5
5 4
4 2
3 2
1 2
2 3
Sample Output
YES
NO
思路
本题就是求有向图里面是否有环。
1.记录每个顶点的入度数,和顶点之间的关系;
2.如果入度数为0,则压入队列;
3.先从这些顶点开始,枚举相连的边,枚举到的顶点入度减一,如果某个顶点的入度为0,则压入队列。依次操作记录入度为0的顶点,如果所有顶点都进过队列,则没有环,否则就有环。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#include<queue>
#include<string>
#include<vector>
#include<utility>
#include<algorithm>
using namespace std;
const int MAXN=1e5+5;
vector<int> g[MAXN];
int ind[MAXN];
bool vis[MAXN];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m,u,v,cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
ind[i]=0;
g[i].clear();
}
for(int i=0;i<m;i++){
scanf("%d%d",&u,&v);
g[u].push_back(v);
ind[v]++;
}
queue<int> q;
for(int i=1;i<=n;i++){
if(ind[i]==0){//入度为0,为起点
q.push(i);
}
}
while(!q.empty()){
int now=q.front();q.pop();
cnt++;
for(int i=0;i<g[now].size();i++){
int to=g[now][i];
ind[to]--;
if(ind[to]==0){
q.push(to);
}
}
}
if(cnt!=n) puts("YES");
else puts("NO");
}
return 0;
}