int main(){ freopen("bcc.out","w",stdout); init(); printG(); //dfnlow(3,-1); bicon(3,-1); printDfnLow(); // getchar(); }
void bicon(int u, int v) { node_pointer ptr; int w; edge e; dfn[u] = low[u] = num++; for(ptr = graph[u]; ptr; ptr = ptr->link) { w = ptr->vertex; printf("w: %d u: %d v: %d dfn[w]: %d dfn[u]: %d \n",w,u,v,dfn[w],dfn[u]); if( dfn[w] < dfn[u] && v!=w) { //v!=w to avoid 1->2 2->1 in undirected graph // dfn[w] < dfn[u] to avoid visited vertex who is decendant of u edges[top].v = u; // 新边压栈,v!=w是防止重复计算无向图中同一条边 //dfn[w]<dfn[u] 是防止重复计算回退边,因为dfs过程中, //遇到的顶点只有两种情况,dfn[w]=-1新点, dfn[w]<dfn[u] //u,w 是回退边。二者的共同点是 dfn[w] < dfn[u],这两种 //边包括了G的所有边,因此对其他边的访问是重复的。 edges[top].w = w; ++top; if(dfn[w]< 0) { //如果是新顶点(未访问过) bicon(w,u); //递归计算 low[u] = MIN(low[u], low[w]);// 更新当前u的low if(low[w] >= dfn[u]) { //如果发现u的孩子w 满足条件,说明u是关节点 printf("New biconnected component:\n"); do{ e = edges[--top]; //此时栈中是上面的bicon压入的访问过的边, //即该关节点下的子树边和回退边 printf("<%d,%d>", e.v, e.w); }while( !(e.v == u && e.w == w)); printf("\n"); } } else if (v!=w){ low[u] = MIN(low[u], dfn[w]); } } } }
bool TopologicalGraph::CheckBiconnected() {if(debug())DebugPrintf(" CheckBionnected"); if(Set().exist(PROP_BICONNECTED))return true; if(nv() < 3 || ne() < 3)return false; if(debug())DebugPrintf("Executing CheckBionnected"); int m = ne(); int n = nv(); if (m==0) return true; svector<tvertex> nvin(-m,m); nvin.SetName("TG:Bicon:nvin"); svector<tvertex> low(0,n); low.SetName("TG:Bicon:low"); if(!DFS(nvin)) // not connected ... return false; _Bicon Bicon(n); int ret = bicon(n,m,nvin,Bicon,low); if(ret) {Prop1<int> isbicon(Set(),PROP_BICONNECTED); Prop1<int> is_con(Set(),PROP_CONNECTED); return true; } return false; }