在有向图中查找循环
Finding the cycle in a directed graph
我正在解决一个问题以确定图形是否包含循环。我使用着色方法解决了它(在已访问的数组中我将标记,如果从未访问过为 0,如果访问过为 1,如果顶点之旅完成为 2)
为此我写了代码:
#include <bits/stdc++.h>
using namespace std;
vector<int> adj[20005];
int vis[20005];
int chk = 0;
void dfs(int u){
if(vis[u]==1) {
chk = 1;
return;
}
if(vis[u]==2) return;
vis[u] = 1;
for(auto v:adj[u]) dfs(v);
vis[u] = 2;
}
int main(){
int N, M; cin>>N>>M;
for(int i = 0; i<M; i++){
int p, q; cin>>p>>q;
adj[p].push_back(q);
}
for(int i = 1; i<=N; i++){
if(vis[i]==1) break;
if(!vis[i]) dfs(i);
}
cout<<(chk?"Yes\n":"No\n");
}
现在,我在想,是否有一种方法可以编写已检测到的循环。我知道大多数人会说 DFS 和回溯,它们非常直观。但是想知道如何实现它。
par[v] - v 的父节点,pr - 先前访问过的节点:
void dfs(int u, int pr = -1){
if(vis[u]==1) {
vector<int> cycle();
int cur = pr;
while(cur != u) {
cycle.push_back(cur);
cur = par[cur]
}
cycle.push_back(u);
chk = 1;
return;
}
if(vis[u]==2) return;
vis[u] = 1;
par[u] = pr;
for(auto v:adj[u]) dfs(v, u);
vis[u] = 2;
}
我正在解决一个问题以确定图形是否包含循环。我使用着色方法解决了它(在已访问的数组中我将标记,如果从未访问过为 0,如果访问过为 1,如果顶点之旅完成为 2) 为此我写了代码:
#include <bits/stdc++.h>
using namespace std;
vector<int> adj[20005];
int vis[20005];
int chk = 0;
void dfs(int u){
if(vis[u]==1) {
chk = 1;
return;
}
if(vis[u]==2) return;
vis[u] = 1;
for(auto v:adj[u]) dfs(v);
vis[u] = 2;
}
int main(){
int N, M; cin>>N>>M;
for(int i = 0; i<M; i++){
int p, q; cin>>p>>q;
adj[p].push_back(q);
}
for(int i = 1; i<=N; i++){
if(vis[i]==1) break;
if(!vis[i]) dfs(i);
}
cout<<(chk?"Yes\n":"No\n");
}
现在,我在想,是否有一种方法可以编写已检测到的循环。我知道大多数人会说 DFS 和回溯,它们非常直观。但是想知道如何实现它。
par[v] - v 的父节点,pr - 先前访问过的节点:
void dfs(int u, int pr = -1){
if(vis[u]==1) {
vector<int> cycle();
int cur = pr;
while(cur != u) {
cycle.push_back(cur);
cur = par[cur]
}
cycle.push_back(u);
chk = 1;
return;
}
if(vis[u]==2) return;
vis[u] = 1;
par[u] = pr;
for(auto v:adj[u]) dfs(v, u);
vis[u] = 2;
}