Luogu3119 草鉴定-Tarjan+Topsort
Solution
简单的$Tarjan$题。
有大佬现成博客 就不写了 → 传送门
Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #define rd read() 6 using namespace std; 7 8 const int N = 1e5 + 5; 9 const int inf = ~0U >> 2; 10 11 int n, m; 12 int head[N], tot, Head[N], Tot; 13 int low[N], dfn[N], cnt; 14 int st[N], tp, col, c[N], val[N], subsz[N], upsz[N], deg[N], bvis[N]; 15 bool vis[N]; 16 17 struct edge { 18 int nxt, fr, to; 19 }e[N], E[N]; 20 21 queue<int> q; 22 23 int read() { 24 int X = 0, p = 1; char c = getchar(); 25 for (; c > '9' || c < '0'; c = getchar()) 26 if (c == '-') p = -1; 27 for (; c >= '0' && c <= '9'; c = getchar()) 28 X = X * 10 + c - '0'; 29 return X * p; 30 } 31 32 void add(int u, int v) { 33 e[++tot].to = v; 34 e[tot].fr = u; 35 e[tot].nxt = head[u]; 36 head[u] = tot; 37 } 38 39 void Add(int u, int v) { 40 E[++Tot].to = v; 41 E[Tot].fr = u; 42 E[Tot].nxt = Head[u]; 43 Head[u] = Tot; 44 } 45 46 void cmin(int &A, int B) { 47 if (A > B) A = B; 48 } 49 50 void cmax(int &A, int B) { 51 if (A < B) A = B; 52 } 53 54 void tarjan(int u) { 55 dfn[u] = low[u] = ++cnt; 56 vis[u] = 1; st[++tp] = u; 57 for (int i = head[u]; i; i = e[i].nxt) { 58 int nt = e[i].to; 59 if (!dfn[nt]) { 60 tarjan(nt); 61 cmin(low[u], low[nt]); 62 } 63 else if (vis[nt]) cmin(low[u], dfn[nt]); 64 } 65 if (low[u] == dfn[u]) { 66 col++; 67 for (; tp;) { 68 int z = st[tp--]; 69 c[z] = col; 70 vis[z] = 0; 71 val[col]++; 72 if (z == u) break; 73 } 74 } 75 } 76 77 void dfs(int u) { 78 vis[u] = 1; 79 for (int i = Head[u]; i; i = E[i].nxt) { 80 int nt = E[i].to; 81 dfs(nt); 82 } 83 } 84 85 int dfs2(int u) { 86 if (bvis[u] == 1) return 1; 87 if (bvis[u] == -1) return 0; 88 if (u == c[1]) return 1; 89 bool flag = false; 90 for (int i = Head[u]; i; i = E[i].nxt) { 91 int nt = E[i].to; 92 if (dfs2(nt)) { 93 flag = true; 94 cmax(upsz[u], upsz[nt] + val[u]); 95 } 96 } 97 bvis[u] = flag ? 1 : -1; 98 return flag; 99 } 100 101 void Topsort() { 102 subsz[c[1]] = val[c[1]]; 103 for (int i = 1; i <= col; ++i) 104 if (!deg[i]) q.push(i); 105 for (int u; !q.empty(); ) { 106 u = q.front(); q.pop(); 107 for (int i = Head[u]; i; i = E[i].nxt) { 108 int nt = E[i].to; 109 if (subsz[u] != -inf) 110 cmax(subsz[nt], subsz[u] + val[nt]); 111 deg[nt]--; 112 if (!deg[nt]) q.push(nt); 113 } 114 } 115 } 116 117 int main() 118 { 119 n = rd; m = rd; 120 for (int i = 1; i <= m; ++i) { 121 int u = rd, v = rd; 122 add(u, v); 123 } 124 for (int i = 1; i <= n; ++i) 125 if (!dfn[i]) tarjan(i); 126 for (int i = 1; i <= m; ++i) { 127 int u = e[i].fr, v = e[i].to; 128 u = c[u], v = c[v]; 129 if (u == v) continue; 130 Add(u, v); 131 deg[v]++; 132 } 133 memset(vis, 0, sizeof(vis)); 134 for (int i = 1; i <= col; ++i) subsz[i] = -inf; 135 dfs(c[1]); 136 Topsort(); 137 bvis[c[1]] = 1; 138 upsz[c[1]] = val[c[1]]; 139 for (int i = 1; i <= col; ++i) 140 if (!vis[i]) dfs2(i); 141 int ans = val[c[1]]; 142 for (int i = 1; i <= m; ++i) { 143 int u = e[i].fr, v = e[i].to; 144 u = c[u]; v = c[v]; 145 if (u == v) continue; 146 if (!vis[v] || !(bvis[u] == 1)) continue; 147 cmax(ans, subsz[v] + upsz[u] - val[c[1]]); 148 } 149 printf("%d\n", ans); 150 }