1. 程式人生 > >割點(割頂)

割點(割頂)

!= min pan return ini graph mem long oid

$Tarjan$大法好$qwq$。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define re register
 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i)
 7 #define repd(i, a, b) for (re int i = a; i >= b; --i)
 8 #define maxx(a, b) a = max(a, b);
 9 #define minn(a, b) a = min(a, b);
10
#define LL long long 11 #define inf (1 << 30) 12 13 inline int read() { 14 int w = 0, f = 1; char c = getchar(); 15 while (!isdigit(c)) f = c == - ? -1 : f, c = getchar(); 16 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ 0), c = getchar(); 17 return w * f;
18 } 19 20 const int maxn = 1e4 + 5, maxm = 1e5 + 5; 21 22 struct Edge { 23 int u, v, pre; 24 }; 25 26 struct Graph { 27 Edge ed[maxm << 1]; 28 int n, m, G[maxn]; 29 void init(int n) { 30 this->n = n; 31 m = 0; 32 memset(G, 0, sizeof(G));
33 } 34 void add(int u, int v) { 35 ed[++m] = (Edge){u, v, G[u]}; 36 G[u] = m; 37 } 38 int dfs_clock, pre[maxn], low[maxn], iscut[maxn]; 39 void dfs(int u, int fa) { 40 pre[u] = low[u] = ++dfs_clock; 41 int child = 0; 42 for (register int i = G[u]; i; i = ed[i].pre) { 43 int v = ed[i].v; 44 if (!pre[v]) { 45 child++; 46 dfs(v, u); 47 minn(low[u], low[v]); 48 if (low[v] >= pre[u]) 49 iscut[u] = 1; 50 } 51 else if (v != fa) minn(low[u], pre[v]); 52 } 53 if (u == fa && child == 1) iscut[u] = 0; 54 } 55 void tarjan() { 56 memset(pre, 0, sizeof(pre)); 57 memset(low, 0, sizeof(low)); 58 memset(iscut, 0, sizeof(iscut)); 59 dfs_clock = 0; 60 rep(i, 1, n) 61 if (!pre[i]) 62 dfs(i, i); 63 int cnt = 0; 64 rep(i, 1, n) 65 if (iscut[i]) 66 cnt++; 67 printf("%d\n", cnt); 68 rep(i, 1, n) 69 if (iscut[i]) 70 printf("%d ", i); 71 } 72 } G; 73 74 int n, m; 75 76 int main() { 77 n = read(), m = read(); 78 G.init(n); 79 rep(i, 1, m) { 80 int u = read(), v = read(); 81 G.add(u, v), G.add(v, u); 82 } 83 G.tarjan(); 84 return 0; 85 }

割點(割頂)