UVa 11324 - The Largest Clique (tarjan)
阿新 • • 發佈:2021-07-17
題目連結:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=2299&mosmsg=Submission+received+with+ID+26582032
縮點以後求最長路,拓撲和記搜都可以
一定要注意所開陣列的大小,邊的陣列不要開成點的,因為陣列開小 WA 了一個小時,實在不行就把陣列使勁往大開
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1010; int T, n, m; int u[50010], v[50010], in[maxn]; vector<int> G[maxn]; int h[maxn], cnt = 0; struct E{ int to, next; }e[50010]; void add(int u, int v){ e[++cnt].to = v; e[cnt].next = h[u]; h[u] = cnt; } int low[maxn], st[maxn], sccno[maxn], sz[maxn], dfn = 0, scc_cnt = 0; stack<int> S; void dfs(int u){ low[u] = st[u] = ++dfn; S.push(u); for(int i = h[u] ; i != -1 ; i = e[i].next){ int v = e[i].to; if(!st[v]){ dfs(v); low[u] = min(low[u], low[v]); } else if(!sccno[v]){ low[u] = min(low[u], st[v]); } } if(low[u] == st[u]){ ++scc_cnt; for(;;){ int x = S.top(); S.pop(); sccno[x] = scc_cnt; ++sz[scc_cnt]; if(x == u) break; } } } void tarjan(){ memset(low, 0, sizeof(low)); memset(st, 0, sizeof(st)); memset(sccno, 0, sizeof(sccno)); dfn = 0, scc_cnt = 0; for(int i = 1 ; i <= n ; ++i){ if(!st[i]) dfs(i); } } int dp[maxn]; vector<int> path; void topo(){ queue<int> q; path.clear(); memset(dp, 0, sizeof(dp)); for(int i = 1 ; i <= scc_cnt ; ++i){ if(!in[i]){ q.push(i); dp[i] = sz[i]; path.push_back(i); } } while(!q.empty()){ int u = q.front(); q.pop(); for(int i = h[u] ; i != -1 ; i = e[i].next){ int v = e[i].to; --in[v]; if(!in[v]){ q.push(v); path.push_back(v); } } } for(auto u : path){ for(int i = h[u] ; i != -1 ; i = e[i].next){ int v = e[i].to; dp[v] = max(dp[v], dp[u] + sz[v]); } } } int DP(int u){ if(dp[u] >= 0) return dp[u]; dp[u] = sz[u]; for(int i = h[u] ; i != -1 ; i = e[i].next){ int v = e[i].to; dp[u] = max(dp[u], DP(v) + sz[u]); } return dp[u]; } ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; } int main(){ scanf("%d", &T); while(T--){ memset(in, 0, sizeof(in)); memset(h, -1, sizeof(h)); cnt = 0; memset(sz, 0, sizeof(sz)); scanf("%d%d", &n, &m); for(int i = 1 ; i <= m ; ++i){ scanf("%d%d", &u[i], &v[i]); add(u[i], v[i]); } memset(sz, 0, sizeof(sz)); tarjan(); memset(h, -1, sizeof(h)); cnt = 0; for(int i = 1 ; i <= m ; ++i){ if(sccno[u[i]] != sccno[v[i]]){ add(sccno[u[i]], sccno[v[i]]); ++in[sccno[v[i]]]; } } int ans = 0; topo(); for(int i = 1 ; i <= n ; ++i) ans = max(ans, dp[i]); // memset(dp, -1, sizeof(dp)); // for(int i = 1; i <= scc_cnt; i++) ans = max(ans, DP(i)); printf("%d\n", ans); } return 0; }