P3388 【模板】割点(割顶)

lalala题面

呐呐,既然是模板那也没什么好说的了,直接看代码里的东西吧~~

 1 #include<set>
 2 #include<map>
 3 #include<list>
 4 #include<queue>
 5 #include<stack>
 6 #include<string>
 7 #include<cmath>
 8 #include<ctime>
 9 #include<vector>
10 #include<bitset>
11 #include<memory>
12 #include<utility>
13 #include<cstdio>
14 #include<sstream>
15 #include<iostream>
16 #include<cstdlib>
17 #include<cstring>
18 #include<algorithm>
19 using namespace std;
20 const int N=100001;
21 
22 int n,m,tot,ans;
23 int h[N],dfn[N],low[N],fa[N];
24 bool vis[N];
25 struct node{
26     int v;
27     int next;
28 }e[2*N];
29 
30 void add(int u,int v){//加边
31     tot++;
32     e[tot].next=h[u],
33     e[tot].v=v,
34     h[u]=tot;
35 }
36 
37 void tarjan(int p){//tarjan+缩点
38     int t=0;
39     dfn[p]=low[p]=++tot;
40     for(int i=h[p];i;i=e[i].next){
41         int v=e[i].v;
42         if(!dfn[v]){
43             fa[v]=fa[p];
44             tarjan(v);
45             low[p]=min(low[p],low[v]);
46             if(low[v]>=dfn[p]&&p!=fa[p]){//在回溯后立即更新
47                 vis[p]=true;
48             }
49             if(p==fa[p]){//特殊情况
50                 t++;
51             }
52         }
53         low[p]=min(low[p],dfn[v]);
54     }
55     if(p==fa[p]&&t>=2){
56         vis[fa[p]]=true;
57     }
58 }
59 
60 int main(){
61     scanf("%d%d",&n,&m);
62     for(int i=1;i<=m;i++){
63         int x,y;
64         scanf("%d%d",&x,&y);
65         add(x,y);//无向图,加两次边
66         add(y,x);
67     }
68     for(int i=1;i<=n;i++){
69         fa[i]=i;
70     }
71     tot=0;
72     for(int i=1;i<=n;i++){
73         if(!dfn[i]){
74             tarjan(i);
75         }
76     }
77     for(int i=1;i<=n;i++){
78         if(vis[i]){
79             ans++;
80         }
81     }
82     printf("%d
",ans);
83     for(int i=1;i<=n;i++){
84         if(vis[i]){
85             printf("%d ",i);
86         }
87     }
88     return 0;
89 }

没了。。

原文地址:https://www.cnblogs.com/hahaha2124652975/p/11155018.html