【模板】Tarjan(强连通、桥、割点)
模板参考了:https://blog.csdn.net/WhiteAndGold/article/details/81842609
感觉试用性挺广的。
求桥:
1 void Tarjan(int u,int inedge){ 2 dfn[u] = low[u] = ++dfn_clock; 3 for(int i = h[u];i!=-1;i = e[i].nex){ 4 int v = e[i].to; 5 if(!dfn[v]){ 6 Tarjan(v,i); 7 low[u] = min(low[u],low[v]); 8 if(low[v] > dfn[u]) bridge[i] = bridge[i^1] = 1; 9 } 10 else if( i != (inedge^1) ) low[u] = min(low[u],dfn[v]); 11 } 12 }
求割点:
1 void tarjan(int x) { 2 dfn[x]=low[x]=++tot; 3 stk[++Top]=x; 4 int cnt=0; 5 for(int i=head[x]; i; i=G[i].nxt) { 6 int y=G[i].to; 7 if(!dfn[y]) { 8 cnt++; 9 tarjan(y); 10 low[x]=min(low[x],low[y]); 11 if(low[y]>=dfn[x]) { 12 mark[x]=1;//是割点 13 BL[++blk].push_back(x); 14 do { 15 BL[blk].push_back(stk[Top--]); 16 } while(y!=stk[Top+1]); 17 } 18 } else { 19 low[x]=min(low[x],dfn[y]); 20 } 21 } 22 if(x==root&&cnt==1)mark[x]=0;//特殊情况不是割点 23 }
强连通:
1 void tarjan(int x) { 2 dfn[x]=low[x]=++tot; 3 stk[++top]=x; 4 vis[x]=1;//入栈标记 5 for(int i=head[x]; i; i=G[i].nxt) { 6 int y=G[i].to; 7 if(!dfn[y]) { 8 tarjan(y); 9 low[x]=min(low[x],low[y]); 10 } else if(vis[y]) { 11 low[x]=min(low[x],dfn[y]); 12 } 13 } 14 if(low[x]==dfn[x]) { 15 int y; 16 cnt++;//强连通分量个数 17 do { 18 y=stk[top--]; 19 vis[y]=0;//出栈去标记 20 col[y]=cnt;//染色标记 21 } while(y!=x); 22 } 23 }