【模板】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 }
View Code

求割点:

 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 }
View Code

强连通:

 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 }
View Code

 

 

例题:poj3352 poj2942

posted @ 2020-03-31 17:30  小布鞋  阅读(63)  评论(0编辑  收藏