[模板]割点(tarjan)

洛谷P3388

注意:记得tarjan的打法

   注意割点的判断条件:子节点个数>2并且为根节点

               当它不为根节点时并且low[to]>dfn[u]

   判断时是在子节点未被记录的时候

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 inline int sc()
 4 {    int x=0,f=1;char ch=getchar();
 5     while(!isdigit(ch)){    if(ch==45)f=-1;ch=getchar();}
 6     while(isdigit(ch)) {    x=x*10+ch-48;ch=getchar();}
 7     return x*f;
 8     }
 9 #define man 100010
10 int n,m;
11 /*edge*/
12 int head[man<<2],num=0;
13 struct edge
14 {    int next,to;}e[man<<2];
15 inline void add(int from,int to)
16 {    e[++num].next=head[from];
17     e[num].to=to;
18     head[from]=num;
19     }    
20     
21 int dep=0,dfn[man],low[man],cnt=0;
22 bool vis[man],sta[man];
23 inline void tarjan(int u,int fa)
24 {    int son=0;
25     low[u]=dfn[u]=++dep;
26     for(int i=head[u];i;i=e[i].next)
27     {    int to=e[i].to;
28         if(!dfn[to])
29         {    son++;
30             tarjan(to,u);
31             low[u]=min(low[u],low[to]);
32             if((fa==-1&&son>=2)||(fa!=-1&low[to]>=dfn[u]))
33              {   if(sta[u]==0) cnt++;sta[u]=1;}
34             }
35         else if(to!=fa)
36             low[u]=min(low[u],dfn[to]);
37         }
38     }
39 int main()
40 {    n=sc();m=sc();
41     for(int i=1,x,y;i<=m;i++)
42     {    x=sc(),y=sc();
43         add(x,y);add(y,x);
44         }
45     for(int i=1;i<=n;i++)
46         if(!dfn[i]) tarjan(i,-1);
47     cout<<cnt<<endl;
48     for(int i=1;i<=n;i++)
49         if(sta[i]) cout<<i<<" ";
50     cout<<endl;
51     return 0;
52     }
53      

 

posted @ 2017-11-04 19:35  Slager_Z  阅读(306)  评论(0编辑  收藏  举报
博客园 首页 私信博主 显示目录 隐藏目录 管理 动画