微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在有向图中找到循环

如何解决在有向图中找到循环

我正在解决一个问题,以确定一个图形是否包含一个循环。我使用着色方法解决了它(在访问过的数组中我会标记,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;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。