洛谷 P3388 模板 割點 割頂 tarjan

2021-08-21 03:33:32 字數 1220 閱讀 8224

題目鏈結

題意:給出乙個n個點m條邊的無向圖,求其割點。

思路:tarjan求割點模板題。

tarjan(求割點):遍歷整個圖,則整個圖可轉化為一棵樹(附帶著有回邊)。設定兩個陣列,dfn[i](記錄搜尋到i的時間),low[i](記錄在i的子樹中通過非父子邊能夠遍歷到的最早的dfn)。

那麼如何判斷乙個點是否是割點?乙個點v有兩種情況。

v為樹根,則當v有不止一棵子樹時,v為割點。

v非根節點,則當v的子樹中沒有邊指向v的祖先時v為割點。(即v的孩子中存在i使得low[i]>=dfn[v])

現在已經知道怎麼判斷乙個點是否為割點了,那如何求low?可以分為兩種情況。

當edge(v,i)為樹邊時,low[v]=min(low[v],low[i])

當edge(v,i)為回邊時,low[v]=min(low[v],dfn[i])

如果是求割邊呢?

edge(v,i)當且僅當low[i]>dfn[v]時,為割邊。

#include #include #include using namespace std;

#define num 110000

#define inf 0x3f3f3f3f

const int p = 1e9+7;

int n,m;

struct edge

e[num<<1];

int link[num]={};

int dfn[num]={},low[num];

int cut[num];

int cutnum=0,cnt=0;

void tarjan(int root,int pre,int v)

if(v==root)

++rs;

}else

low[v]=min(low[v],dfn[x]);

}if(v==root&&rs>1)

cut[++cutnum]=root;

}int main()

for(int i=1;i<=n;++i)//整個無向圖可能不連通

if(!dfn[i])tarjan(i,i,i);

sort(cut+1,cut+1+cutnum);

printf("%d\n",cutnum);

for(int i=1;i<=cutnum;++i)

printf("%d ",cut[i]);

}

洛谷 P3388 模板 割點(割頂)

割點 給出乙個n個點,m條邊的無向圖,求圖的割點。輸入格式 第一行輸入n,m 下面m行每行輸入x,y表示x到y有一條邊 輸出格式 第一行輸出割點個數 第二行按照節點編號從小到大輸出節點,用空格隔開 輸入樣例 1 6 7 1 21 3 1 42 5 3 54 5 5 6 輸出樣例 1 1 5 n,m均...

洛谷P3388 模板 割點(割頂)

題目大意 求出乙個無向圖的割點 題解 tarjan 若乙個點為根節點 起始節點 只需要判斷它有多少個兒子,若不是根節點,假如 low v geqslant dfn v 就說明 v 沒有返祖邊,即該節點 u 為割點。卡點 1.多輸出了一些數 2.沒有去重 c code include include ...

P3388 模板 割點(割頂)

割點 題目描述 給出乙個n個點,m條邊的無向圖,求圖的割點。輸入格式 第一行輸入n,m 下面m行每行輸入x,y表示x到y有一條邊 輸出格式 第一行輸出割點個數 第二行按照節點編號從小到大輸出節點,用空格隔開 輸入樣例 1 複製6 7 1 21 3 1 42 5 3 54 5 5 6輸出樣例 1 複製...