1. 程式人生 > >tarjan相關模板

tarjan相關模板

scanf tdi main puts com 連通塊 math spl 一個

感性理解:

o(* ̄︶ ̄*)o ^_^ \(^o^)/~

技術分享圖片

1.

當根節點有大於兩個兒子時,割掉它,剩下的點必然不聯通(有兩個強連通分量),則他為割點。

那麽對於非根節點,在無向圖G中,剛且僅當點u存在一個可遍歷到的後代v,且點v無法走回點u的前輩時,點u就為割點。

洛谷P3388

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int N=1e5+2;
 5 int n,m,idx,cnt,tot,h[N];
 6 struct node{
 7     int v,ne;
 8 }e[N*3];
 9 int ans[N];
10 void add(int u,int v)
11 {
12     tot++;e[tot]=(node){v,h[u]};h[u]=tot;
13 }
14 int dfn[N],low[N];
15 bool cut[N];
16 void tarjan(int u,int fa)
17 {
18     dfn[u]=low[u]=++idx;
19     int ch=0;
20     for(int i=h[u],rr;i;i=e[i].ne)
21     {
22         rr=e[i].v;
23         if(!dfn[rr])
24         {
25             tarjan(rr,u);
26             low[u]=min(low[u],low[rr]);
27             if(low[rr]>=dfn[u] && u!=fa) cut[u]=1;
28             ch++;
29         }
30         low[u]=min(low[u],dfn[rr]);
31     }
32     if(ch>=2&&u==fa) cut[u]=1;
33 }
34 int main()
35 {
36     scanf("%d%d",&n,&m);
37     for(int i=1,x,y;i<=m;++i)
38     {
39         scanf("%d%d",&x,&y);
40         add(x,y);add(y,x);
41     }
42     tot=0;
43     for(int i=1;i<=n;++i)
44      if(!dfn[i]) tarjan(i,i);
45     for(int i=1;i<=n;++i)
46      if(cut[i]) ans[++tot]=i;
47     printf("%d\n",tot);
48     for(int i=1;i<=tot;++i) printf("%d ",ans[i]); 
49     return 0;
50 }
割點模板

=================================================================================================技術分享圖片

ZOJ2588

技術分享圖片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+2;
 4 int n,m,idx,cnt,tot,h[N];
 5 struct node{
 6     int v,ne,id,fg; //會有重邊,所以標記一下, 
 7 }e[N*3];//註意,圖中可能有重邊,只要頂點u和v之間有重邊,則這些重邊任何一條都不可能是割邊。 
 8 int ans[N],fg;
 9 void add(int u,int v,int id)
10 {
11     fg=1;
12     for(int i=h[u];i;i=e[i].ne)
13         if(e[i].v==v) e[i].fg=0,fg=0;
14     tot++;e[tot]=(node){v,h[u],id,fg};h[u]=tot;
15 }
16 int dfn[N],low[N];
17 void tarjan(int u,int fa)
18 {
19     dfn[u]=low[u]=++idx;
20     for(int i=h[u],rr;i;i=e[i].ne)
21     {
22         rr=e[i].v;
23         if(rr==fa) continue;
24         if(!dfn[rr])
25         {
26             tarjan(rr,u);
27             low[u]=min(low[u],low[rr]);
28             if(low[rr]>dfn[u] && e[i].fg) ans[++tot]=e[i].id; 
29         }
30         low[u]=min(low[u],dfn[rr]);
31     }
32 }
33 int T;
34 int main()
35 {
36     scanf("%d",&T);
37     while(T--)
38     {
39        tot=0;idx=0;
40        scanf("%d%d",&n,&m);
41        for(int i=1;i<=n;++i) h[i]=0,dfn[i]=0,low[i]=0;
42        for(int i=1,x,y;i<=m;++i)
43        {
44          scanf("%d%d",&x,&y);
45          add(x,y,i);add(y,x,i);
46        }tot=0;
47        for(int i=1;i<=n;++i)
48         if(!dfn[i]) tarjan(i,i);
49        printf("%d\n",tot);
50        sort(ans+1,ans+tot+1);
51        if(tot)
52        {
53             printf("%d",ans[1]);
54             for(int i=2;i<=tot;++i) printf(" %d",ans[i]);
55          printf("\n");
56        }
57        if(T)   printf("\n");
58     }
59     return 0;
60 }
61 /*
62 Sample Input
63  2
64 
65 6 7
66 1 2
67 2 3
68 2 4
69 5 4
70 1 3
71 4 5
72 3 6
73 
74 10 16
75 2 6
76 3 7
77 6 5
78 5 9
79 5 4
80 1 2
81 9 8
82 6 4
83 2 10
84 3 8
85 7 9
86 1 4
87 2 4
88 10 5
89 1 6
90 6 10
91 
92 Sample Output
93  2
94 3 7
95 
96 1
97 4 
98 
99 */
割邊

==================================================================================================

技術分享圖片

至於邊-雙連通分量是指在一個無向圖中兩點間至少有兩條路徑,且路徑中的邊不同。

邊-雙連通分量中一定沒有橋。而橋是指當刪去這個邊時,連通塊的數量會增加。

51nod 1076

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5
#include<string> 6 #include<cmath> 7 using namespace std; 8 const int N=3e5+10; 9 int n,m,tot,h[N]; 10 struct node{ 11 int v,ne; 12 }e[N*4]; 13 int dfn[N],low[N],idx; 14 void add(int u,int v) 15 { 16 tot++;e[tot]=(node){v,h[u]};h[u]=tot; 17 } 18 bool in[N]; 19 int Q,x,y,bg[N],s[N],top; 20 void dfs(int u,int fa) 21 { 22 dfn[u]=low[u]=++idx; 23 s[++top]=u;in[u]=1; 24 for(int i=h[u],rr;i;i=e[i].ne) 25 { 26 rr=e[i].v; 27 if(rr==fa) continue; 28 if(!dfn[rr]) 29 { 30 dfs(rr,u); 31 low[u]=min(low[u],low[rr]); 32 }else if(in[rr]) low[u]=min(low[u],low[rr]); 33 } 34 if(low[u]==dfn[u]) 35 { 36 do{ 37 in[s[top]]=0; 38 bg[s[top]]=u; 39 }while(s[top--]!=u); 40 } 41 } 42 int main() 43 { 44 scanf("%d%d",&n,&m); 45 for(int i=1;i<=m;++i) 46 { 47 scanf("%d%d",&x,&y); 48 add(x,y);add(y,x); 49 } 50 for(int i=1;i<=n;++i) 51 if(!dfn[i]) dfs(i,i); 52 scanf("%d",&Q); 53 while(Q--) 54 { 55 scanf("%d%d",&x,&y); 56 if(bg[x]==bg[y]) puts("Yes"); 57 else puts("No"); 58 } 59 return 0; 60 }
代碼

tarjan相關模板