【HihoCoder 1435 --- Circle Detect】DFS
題目來源:點擊進入【HihoCoder 1435 — 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 Input
2
5 5
1 2
2 3
4 5
5 4
4 2
3 2
1 2
2 3
Sample Output
YES
NO
解題思路
根據dfs遍歷走過的路,直到沒法走或者走到之前走過的路,注意本題是無向圖。所以記得標記三種情況:
還沒被DFS訪問的點是白色的,初始時所有點都是白色的
如果點u已經被DFS訪問過,但是u的子節點還未全部被訪問到,那麼把u染成灰色
如果點u以及u的子節點都被訪問過了,從u回溯到u的父節點時,將u染成黑色
如果在DFS的過程中我們沿着有向邊到達了一個灰色節點,則說明圖中有環;如果從未到達過灰色節點,說明沒有環。
AC代碼(C++):
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 100005;
vector<int> v[MAXN];
int vis[MAXN];
bool dfs(int x){
vis[x]=1;
int len=v[x].size();
for(int i=0;i<len;i++){
if(vis[v[x][i]]==1) return true;
else if(vis[v[x][i]]==0 && dfs(v[x][i])) return true;
}
vis[x]=2;
return false;
}
int main(){
SIS;
int t,n,m,x,y;
cin >> t;
while(t--){
bool flag=false;
cin >> n >> m;
for(int i=1;i<=n;i++) v[i].clear(),vis[i]=0;
while(m--){
cin >> x >> y;
v[x].push_back(y);
}
for(int i=1;i<=n;i++){
if(!vis[i] && dfs(i)){
flag=true;
break;
}
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}