題目鏈結
題意:給出乙個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 複製...