【模板】双连通分量和强连通分量

来源:互联网 发布:python和php哪个简单 编辑:程序博客网 时间:2024/05/08 07:07

双连通分量

#include<cstdio>#include<cstring>#include<vector>#define maxn 10005#define maxm 1000005using namespace std;struct Edge{int u,v;}e[maxm];int n,m,tot,stamp,dfn[maxn],low[maxn],bccno[maxn],bcc_cnt;vector<int>vec[maxn];bool g[maxn][maxn],isbridge[maxm];void tarjan(int index,int fa){    int tmp;    dfn[index]=low[index]=++stamp;    for(int i=0;i<vec[index].size();i++){        tmp=e[vec[index][i]].v;        if(!dfn[tmp]){            tarjan(tmp,index);            low[index]=min(low[index],low[tmp]);            if(low[tmp]>dfn[index])                isbridge[vec[index][i]]=isbridge[vec[index][i]^1]=1;        }        else if(dfn[tmp]<dfn[index] && tmp!=fa){            low[index]=min(low[index], dfn[tmp]);        }    }}void dfs(int index){    dfn[index]=1;    bccno[index]=bcc_cnt;    for(int i=0;i<vec[index].size();i++){        int tmp=vec[index][i];        if(isbridge[tmp])            continue;        if(!dfn[e[tmp].v]){            dfs(e[tmp].v);        }    }}void find_ebcc(){    bcc_cnt=stamp=0;    memset(dfn,0,sizeof(dfn));    memset(low,0,sizeof(low));    memset(isbridge,0,sizeof(isbridge));    memset(bccno,0,sizeof(bccno));    for(int i=1;i<=n;i++)        if(!dfn[i])            tarjan(i, -1);    memset(dfn,0,sizeof(dfn));    for(int i=1;i<=n;i++){        if(!dfn[i]){            bcc_cnt++;            dfs(i);        }    }               }void Addedges(int u,int v){    e[++tot].u=u;e[tot].v=v;    vec[u].push_back(tot);    swap(u,v);    e[++tot].u=u;e[tot].v=v;    vec[u].push_back(tot);}

强连通分量

#include<bits/stdc++.h>using namespace std;const int maxn=105;vector<int>G[maxn];int n,m,pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;stack<int>S;void dfs(int u){    pre[u]=lowlink[u]=++dfs_clock;    S.push(u);    for(int i=0;i<G[u].size();i++){        int v=G[u][i];        if(!pre[v]){            dfs(v);            lowlink[u]=min(lowlink[u],lowlink[v]);        }else if(!sccno[v]){            lowlink[u]=min(lowlink[u],pre[v]);        }    }    if(lowlink[u]==pre[u]){        scc_cnt++;        for(;;){            int x=S.top();S.pop();            sccno[x]=scc_cnt;            if(x==u) break;        }    }    return ;}void find_scc(int n){    dfs_clock=scc_cnt=0;    memset(sccno,0,sizeof(sccno));    memset(pre,0,sizeof(pre));    for(int i=1;i<=n;i++){        if(!pre[i]) dfs(i);    }    return ;}void Addedges(int u,int v){    G[u].push_back(v);}
0 0
原创粉丝点击