无向图求双连通分量以及桥

来源:互联网 发布:excel 2013数据有效性 编辑:程序博客网 时间:2024/06/04 20:39
<code>
void pbc_dfs(int u, int parent) {//求双连通分量中的边    dfn[u] = low[u] = dfn_now++;    foreach e in adjacent list [u] {        v = e->v;        if (v != parent && dfn[v] < dfn[u]) {            stack.push(Edge(u, v));            if (0 != dfn[v])low[u] = min(low[u], dfn[v]);            else {                pbc_dfs(v, u);                low[u] = min(low[u], low[v]);                if (low[v] >= dfn[u]) { // u is a cut point //此处会枚举所有的双连通分量                    do {                        Edge edg = stack.pop();                        ...(some operation)                    } while(edg is not uv);                    ++component_id;                }            }        }    }}


</code>





<code>
int dfn[M],low[M],index;void tarjan(int u,int parent){dfn[u]=low[u]=index++;//应当小心index,可能会出现报错的情况for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(dfn[v]!=0&&v!=pa){//如果v为u的父亲的话,那么就没意思了。可以逻辑一下low[u]=min(low[u],dfn[v]);}else if(dfn[v]==0){tarjan(v,u);low[u]=min(low[v],low[u]);if(dfn[u]<low[v]){//cout<<" == "<<u<<v<<endl;match(u,v);}}}}void solve(int n){memset(dfn,0,sizeof(dfn));memset(fa,-1,sizeof(fa));index=1;for(int i=1;i<=n;i++){if(dfn[i]==0){//可能整张图本身就不连通,而是由多个联通块组成tarjan(i,-1);}}}


</code>