【学习/模板】tarjan割点
生活随笔
收集整理的這篇文章主要介紹了
【学习/模板】tarjan割点
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?P3388 【模板】割點(割頂)
tarjan爺爺造福世界
- 割點適用于無向圖, 所以low數組定義發生變化,不再是最早能追溯到的棧中節點編號(因為是無向邊,沒有意義), 而是一直往下走能繞到的最早的割點編號
- 在tarjan求強連通分量是low[u] = min(low[u], dfn[v]) 與 low[u] = min(low[u], low[v]) 等價 但在求割點時只能用前面的qwq
- 原因:在求強連通分量時,如果v已經在棧中,那么說明u,v一定在同一個強連通分量中,所以到最后low[u]=low[v]是必然的,提前更新也不會有問題;
代碼qwq
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 const int maxn = 20020, maxm = 100010; 5 int n, m, num = 0, tim = 0, tot = 0; 6 int head[maxm], dfn[maxn], low[maxn]; 7 bool cut[maxn]; 8 struct edge { 9 int nxt, to; 10 }e[maxm<<1]; 11 int read() { 12 char ch = getchar(); int x = 0, f = 1; 13 while(ch<'0'||ch>'9') {if(ch == '-') f = -1; ch = getchar();} 14 while(ch>='0'&&ch<='9') {x = x * 10 + ch - '0'; ch = getchar();} 15 return x * f; 16 } 17 void add(int from, int to) { 18 e[++num].nxt = head[from]; 19 e[num].to = to; 20 head[from] = num; 21 } 22 void tarjan(int u, int fa) { 23 dfn[u] = low[u] = ++tim; 24 int child = 0; 25 for(int i = head[u]; i; i = e[i].nxt) { 26 int v = e[i].to; 27 if(!dfn[v]) { 28 tarjan(v, fa); 29 low[u] = min(low[u], low[v]); 30 if(low[v] >= dfn[u] && u != fa) cut[u] = 1; 31 //不為根節點, 則對于邊(u, v) ,如果low[v]>=dfn[u],此時u就是割點 32 if(u == fa) child++; 33 } 34 low[u] = min(low[u], dfn[v]);/**/ 35 } 36 if(child >= 2 && u == fa) cut[u] = 1; 37 //如果是根節點 , 有兩棵及以上的子樹, 即為割點 38 } 39 int main() { 40 scanf("%d%d", &n, &m); 41 for(int i = 1; i <= m; i++) { 42 int x = read(), y = read(); 43 add(x, y), add(y, x); 44 } 45 for(int i = 1; i <= n; i++) 46 if(!dfn[i]) tarjan(i, i); 47 for(int i = 1; i <= n; i++) 48 if(cut[i]) tot++; 49 printf("%d\n", tot); 50 for(int i = 1; i <= n; i++) 51 if(cut[i]) printf("%d ", i); 52 return 0; 53 }我覺得比縮點好懂QAQ
轉載于:https://www.cnblogs.com/Hwjia/p/9856125.html
總結
以上是生活随笔為你收集整理的【学习/模板】tarjan割点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows Presentation
- 下一篇: k8s/01开启云原生之门(Mooc)