【模板】割点(割顶)
生活随笔
收集整理的這篇文章主要介紹了
【模板】割点(割顶)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目背景
割點
題目描述
給出一個n個點,m條邊的無向圖,求圖的割點。
輸入輸出格式
輸入格式:第一行輸入n,m
下面m行每行輸入x,y表示x到y(tǒng)有一條邊
輸出格式:第一行輸出割點個數(shù)
第二行按照節(jié)點編號從小到大輸出節(jié)點,用空格隔開
輸入輸出樣例
輸入樣例#1:6 7 1 2 1 3 1 4 2 5 3 5 4 5 5 6 輸出樣例#1:
1 5
說明
n,m均為100000
tarjan 圖不一定聯(lián)通!!!
思路
dfs求割點;
在DFS搜索樹,我們可以發(fā)現(xiàn)有兩類節(jié)點可以成為割點:
2即n->v邊中l(wèi)ow[v]>=dfn[u];
代碼實現(xiàn)
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=3e5; 5 inline int min_(int x,int y){return x<y?x:y;} 6 int n,m; 7 int a,b; 8 int h[maxn],hs,et[maxn],en[maxn]; 9 void add(int u,int v){ 10 ++hs,et[hs]=v,en[hs]=h[u],h[u]=hs; 11 ++hs,et[hs]=u,en[hs]=h[v],h[v]=hs; 12 } 13 int s[maxn],ss; 14 int dfn[maxn],dfns,low[maxn],v[maxn]; 15 void tarjan(int k,int f){ 16 dfn[k]=low[k]=++dfns; 17 for(int i=h[k];i;i=en[i]) 18 if(et[i]!=f){ 19 if(dfn[et[i]]){ 20 low[k]=min_(low[k],dfn[et[i]]); 21 } 22 else{ 23 tarjan(et[i],k); 24 low[k]=min_(low[k],low[et[i]]); 25 if(low[et[i]]>=dfn[k]) ++v[k]; 26 } 27 } 28 if(f&&v[k]) s[++ss]=k; 29 if(!f&&v[k]>1) s[++ss]=k; 30 } 31 int main(){ 32 scanf("%d%d",&n,&m); 33 for(int i=1;i<=m;i++){ 34 scanf("%d%d",&a,&b); 35 add(a,b); 36 } 37 for(int i=1;i<=n;i++){ 38 if(!dfn[i]){ 39 dfns=0; 40 tarjan(i,0); 41 } 42 } 43 sort(s+1,s+ss+1); 44 printf("%d\n",ss); 45 for(int i=1;i<=ss;i++) printf("%d ",s[i]); 46 putchar('\n'); 47 return 0; 48 }感謝;
http://www.cnblogs.com/en-heng/p/4002658.html
助我一A;
轉(zhuǎn)載于:https://www.cnblogs.com/J-william/p/7044352.html
總結(jié)
以上是生活随笔為你收集整理的【模板】割点(割顶)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 24、Java并发性和多线程-信号量
- 下一篇: 书写神器——markdown