边双+点双模板

点双

vector<int> G[maxn], bcc[maxn];
int n, m, dfstime, bcccnt;
bool iscut[maxn];
int bccnu[maxn], pre[maxn];
stack<pair<int, int> > s;

int dfs(int u, int fa){
    int lowu = pre[u] = ++dfstime;
    int child = 0;
    int len = G[u].size();
    for (int i = 0; i < len; i++){
        int v = G[u][i];
        pair<int, int> p = mk(u, v);
        if (pre[v] == -1){
            child++;
            s.push(p);
            int lowv = dfs(v, u);
            lowu = min(lowu, lowv);
            if (lowv >= pre[u]){
                iscut[u] = true;
                bcccnt++;
                while (true){
                    pair<int, int> pr = s.top(); s.pop();
                    if (bcccnt != bccnu[pr.fi]) bccnu[pr.fi] = bcccnt, bcc[bcccnt].pb(pr.fi);
                    if (bcccnt != bccnu[pr.se]) bccnu[pr.se] = bcccnt, bcc[bcccnt].pb(pr.se);
                    if (pr.fi == u && pr .se == v) break;
                }
            }
        }
        else if (pre[v] < pre[u] && v != fa){
            s.push(p); lowu = min(lowu, pre[v]);
        }
    }
    if (fa < 0 && child == 1) iscut[u] = false;
    return lowu;
}

void find_bcc(){
    dfstime = bcccnt = 0;
    memset(iscut, false, sizeof(iscut));
    memset(bccnu, 0, sizeof(bccnu));
    memset(pre, -1, sizeof(pre));
    dfs(1, -1);
}

 

边双

stack<int> s;
vector<int> G[maxn], bcc[maxn];
int bccno[maxn], pre[maxn], iscut[maxn];
int n, m, bcc_cnt, dfstime;

int dfs(int u, int fa){
    int lowu = pre[u] = ++dfstime;
    int len = G[u].size();
    int child = 0;
    s.push(u);
    for (int i = 0; i < len; i++){
        int v = G[u][i];
        if (pre[v] == -1){
            child++;
            int lowv = dfs(v, u);
            lowu = min(lowv, lowu);
            if (lowv > pre[u]){
                iscut[u] = true;
            }
        }
        else if (pre[v] < pre[u] && v != fa){
            lowu = min(lowu, pre[v]);
        }
    }
    if (lowu == pre[u]){
        bcc_cnt++;
        while (true){///边双连通分量是不存在重点的
            int v = s.top(); s.pop();
            bcc[bcc_cnt].pb(v);
            if (v == u) break;
        }
    }
    if (fa == -1 && child == 1) iscut[u] = false;
    return lowu;
}

 

posted @ 2016-09-23 13:38  知る奇迹に  阅读(340)  评论(0编辑  收藏  举报