zoukankan      html  css  js  c++  java
  • 模板汇总——Tarjian

    1. 单向边  + 新图建边

    int belong[N], dfn[N], low[N], now_time, scc_cnt;
    stack<int> s;
    void dfs(int u){
        dfn[u] = low[u] = ++now_time;
        s.push(u);
        for(int i = head[u]; ~i; i = nt[i]){
            if(!dfn[to[i]]) dfs(to[i]);
            if(!belong[to[i]]) low[u] = min(low[u], low[to[i]]);
        }
        if(dfn[u] == low[u]){
            ++scc_cnt;
            int now;
            while(1){
                now = s.top(); s.pop();
                belong[now] = scc_cnt;
                if(now == u) break;
            }
        }
    }
    void scc(int n){
        now_time = scc_cnt = 0;
        for(int i = 1; i <= n; ++i)
            if(!belong[i]) dfs(i);
        int v;
        for(int i = 1; i <= n; ++i){
            for(int j = head[i]; ~j; j=nt[j]){
                v = to[j];
                if(belong[v] != belong[i]){
                        vc[belong[i]].pb(belong[v]);
                }
            }
        }
    }
    View Code

    2.双向边 + 新图建边

    int belong[N], dfn[N], low[N], now_time, scc_cnt;
    vector<int> vc[N];
    vector<pll> e[N];
    stack<int> s;
    void dfs(int u, int id){
        dfn[u] = low[u] = ++now_time;
        s.push(u);
        for(int i = head[u]; ~i; i = nt[i]){
            if(i == (id^1)) continue;
            if(!dfn[to[i]]) dfs(to[i], i);
            if(!belong[to[i]]) low[u] = min(low[u], low[to[i]]);
        }
        if(dfn[u] == low[u]){
            ++scc_cnt;
            int now;
            while(1){
                now = s.top(); s.pop();
                belong[now] = scc_cnt;
                if(now == u) break;
            }
        }
    }
    void scc(int n){
        for(int i = 1; i <= n; ++i) dfn[i] = low[i] = belong[i] = 0;
        while(!s.empty()) s.pop();
        now_time = scc_cnt = 0;
        for(int i = 1; i <= n; ++i)
            if(!belong[i]) dfs(i, -1);
        for(int i = 0, u, v; i < tot; i += 2){
            u = to[i], v = to[i+1];
            u = belong[u], v = belong[v];
            if(u != v) e[u].pb(pll(v,i/2+1)), e[v].pb(pll(u,i/2+1));
        }
    }
    View Code

    3.边双连通分量。

      边双连通就是没有一个桥。

      桥的定义就是断开这个边能使得图分为2部分。

      先找到桥, 然后再dfs不经过桥所能到达的点都是同一个边双联通分量。  

    int dfn[N], low[N], dtot;
    void Tarjan(int o, int u){
        dfn[u]= low[u] = ++dtot;
        for(int i = head[u]; ~i; i = nt[i]){
            int v = to[i];
            if(!dfn[v]){
                Tarjan(u, v);
                low[u] = min(low[u], low[v]);
                if(low[v] > dfn[u])
                    bridge[i] = bridge[i^1] = 1;
            }
            else if(v != o)
                low[u] = min(low[u], dfn[v]);
        }
    }
    int c[N], dcc;
    void dfs(int u){
        c[u] = dcc;
        for(int i = head[u]; i; i = nt[i]){
            int v = to[i];
            if(c[v] || bridge[i]) continue;
            dfs(v);
        }
    }
    int ok[N];
    vector<pll> vc[N];
    void e_dcc(){
        for(int i = 1; i <= n; ++i)
            if(!dfn[i]) Tarjan(0, i);
        for(int i = 1; i <= n; ++i)
            if(!c[i]) {
                ++dcc;
                dfs(i);
            }
        for(int i = 0; i <= tot; i += 2){
            int u = to[i^1], v = to[i];
            u = c[u], v = c[v];
            if(u == v){
                ok[u] |= val[i];
            }
            else {
                vc[u].pb({v,val[i]});
                vc[v].pb({u,val[i]});
            }
        }
    }
    View Code
  • 相关阅读:
    Android Studio快速定位当前文件所在的位置
    LeetCode:Search Insert Position
    apk当安装程序将文件复制到手机自带的指定文件夹
    《UNIX级别编程环境》注意读出信号(2)
    iOS:删除小程序
    百度CSND博客在搜索栏中显示图片
    HDU4893:Wow! Such Sequence!(段树lazy)
    Google I/O 2014? No,Android I/O 2014
    Android Push Notifications using Google Cloud Messaging (GCM), PHP and MySQL
    自己动手写CPU 笔记
  • 原文地址:https://www.cnblogs.com/MingSD/p/10097365.html
Copyright © 2011-2022 走看看