在圖論中,連通圖基於連通的概念。在乙個無向圖 g 中,若從頂點i到頂點j有路徑相連(當然從j到i也一定有路徑),則稱i和j是連通的。如果 g 是有向圖,那麼連線i和j的路徑中所有的邊都必須同向。如果圖中任意兩點都是連通的,那麼圖被稱作連通圖。如果此圖是有向圖,則稱為強連通圖(注意:需要雙向都有路徑)。圖的連通性是圖的基本性質。
——摘自度娘
通俗易懂,不在解釋。
舉個例子吧:
如上圖,各個節點皆可以到達任意節點,所以該圖為連通圖。
在乙個無向圖中,如果有乙個頂點集合,刪除這個頂點集合以及這個集合中所有頂點相關聯的邊以後,圖的連通分量增多,就稱這個點集為割點集合。
如果某個割點集合只含有乙個頂點x(也即是乙個割點集合),那麼x稱為乙個割點。
——摘自度娘
了解完定義之後,不難通過定義來求出圖的割點——暴力dfs。
即是:從1到n遍歷每乙個點,每次遍歷到這個點時,只需要刪除該點,判斷刪除後是否會增加聯通量即可。
這種方法時間複雜度最壞為\(o(n×(n+m))\),只要資料大一點就會被卡爆,這裡不詳細敘述。
可以參考本人的tarjan演算法縮點部落格
依然定義:dfn(時間戳),low(該集合中最早遍歷到的點的時間戳)
觀察上圖,可以發現割點求法可以分成兩種情況討論。
若該點為根節點,若有該節點擁有兩個及以上互不相連的子樹,則刪除該點會得到這些子樹。所以該點為割點。
(now == root && child >= 2)
若該點不為根節點,若不存在可以在dfs中可以遇到已訪問節點的連邊時(通俗的說,就是不可以找到回去的路),則該點為割點。
(now != root && low[next] >= dfn[now])
low的值可以證明發現:
low的初始值為該節點的時間戳。
即是:low[now]=dfn[now]。
若當前結點now的所鏈結點next正在被訪問,則low[now]=min(low[now],dfn[next])。
若當前結點now的所鏈結點next未被訪問,則
low[now]=min(low[now],low[next])。
void tarjan(int now, int father, int root)
tarjan(next, now, root);
low[now] = min(low[now], low[next]);
if(now == root && child >= 2)//處理情況一
cut[now] = true;
else if(now != root && low[next] >= dfn[now])//處理情況二
cut[now] = true;
} if(next != father)
low[now] = min(low[now], dfn[next]);//更新low值 }}
void build()
附上一道板題
割點給出乙個\(n\)個點,\(m\)條邊的無向圖,求圖的割點。
第一行輸入兩個正整數\(n,m\)。
下面\(m\)行每行輸入兩個正整數\(x,y\)表示\(x\)到\(y\)有一條邊。
第一行輸出割點個數。
第二行按照節點編號從小到大輸出節點,用空格隔開。
輸入
6 7
1 21 3
1 42 5
3 54 5
5 6
輸出1
5
思路
板題,套上即可。
#include #include using namespace std;
const int maxn = 2e4 + 5;
vectorv[maxn];
int dfn[maxn], low[maxn];
bool cut[maxn];
int tim, cnt;
int n, m;
void read();
void build();
void tarjan(int, int, int);
int main()
void build()
void tarjan(int now, int father, int root)
tarjan(next, now, root);
low[now] = min(low[now], low[next]);
if(now == root && child >= 2)
cut[now] = true;
else if(now != root && low[next] >= dfn[now])
cut[now] = true;
} if(next != father)
low[now] = min(low[now], dfn[next]); }}
void read()
}
tarjan演算法求割點割邊
在上一節我們已經知道tarjan演算法可以求聯通圖,在這裡我們也運用tarjan的思想求割點與割邊,首先我們先來說說割點,那麼什麼事割點呢,先來看一張圖 a 來自網路 在 a 圖中,我們將a點以及與a點相連的邊全部去除,會發現這個聯通圖被分成了倆個聯通圖,乙個是節點f,另外乙個是餘下的所有的節點組成...
求割點模板(tarjan演算法思路)
想看更多模板,貼上求割點模板 const int n 110 struct data tu n n int head n low n dfn n dfn記錄某個點被訪問到的次數,low記錄某個點或其子樹回邊的最小步數的點 bool cut n 表示該點是否為割點 int ip int step,rt...
Tarjan演算法求橋和割點
預備定義 low u 定義為u或者u的子樹中能夠通過 非父子邊 追溯到的最早的節點的dfs開始時間 d u 表示dfs過程中u的進棧時間 割點 無向連通圖中,如果刪除某點後,圖變成不連通,則稱該點為割點。橋 無向連通圖中,如果刪除某邊後,圖變成不連通,則稱該邊為橋。判斷割點方法 1 u為樹根,且u有...