【图论】简单环

    stack<int> S;
    vector<int> circle;
    int dep[100005];
    void dfs(int u, int p, int d) {
        dep[u] = d;
        if(!circle.empty())
            return;
        //printf("u=%d\n", u);
        vis[u] = 1;
        S.push(u);
        int latestA = 0;
        for(int v : G[u]) {
            if(vis[v] == 2)
                continue;
            if(v == p)
                continue;
            if(vis[v] == 1) {
                if(latestA == 0 || dep[v] > dep[latestA])
                    latestA = v;
            }
        }
        if(latestA) {
            while(vis[latestA] == 1) {
                assert(S.size());
                circle.push_back(S.top());
                vis[S.top()] = 2;
                S.pop();
            }
            return;
        }
        for(int v : G[u]) {
            if(v == p)
                continue;
            if(vis[v]) {
                assert(vis[v] == 2);
                continue;
            }
            dfs(v, u, d + 1);
        }
        if(!S.empty())
            S.pop();
        vis[u] = 2;
    }

利用dfs的性质,每个点先遍历看看是否有反向边,若有反向边则记录最近的祖先。

posted @ 2020-12-12 19:27  purinliang  阅读(164)  评论(0编辑  收藏  举报