然后是才发现洛谷的模板题之前一直没过,看了一下才发现是建新图时把方向建返了....这猪脑子。
于是重新学了一遍Tarjan的思路,果然靠背板子的话真就一点都回忆不起来啊。
又pass一个点叻!yep!
#include<bits/stdc++.h> const int N = 100005; using namespace std; struct Node { int nex, v; Node(int nex = 0, int v = 0) : nex(nex), v(v) { } } Edge[N]; struct node { int nex, v; node(int nex = 0, int v = 0) : nex(nex), v(v) { } } Edgeco[N]; int stot, h[10005]; void add(int u, int v) { Edge[++stot] = Node(h[u], v); h[u] = stot; } int stotco, hco[10005]; void addco(int u, int v) { Edgeco[++stotco] = node(hco[u], v); hco[u] = stotco; } int dfn[10005], low[10005], idc, color[10005], tp, stk[50005], cnt, sum[10005], val[10005]; void Tarjan(int u) { dfn[u] = low[u] = ++ idc; stk[++tp] = u; for(int i = h[u]; i; i = Edge[i].nex) { int v = Edge[i].v; if(!dfn[v]) { Tarjan(v); low[u] = min(low[v], low[u]); } else if(!color[v]) low[u] = min(dfn[v], low[u]); } if(dfn[u] == low[u]) { cnt ++; int x; do { x = stk[tp--]; color[x] = cnt; sum[cnt] += val[x]; } while(x != u); } } int n, m; int f[10005]; void dfs(int u) { if(f[u]) return ; f[u] = sum[u]; for(int i = hco[u]; i; i = Edgeco[i].nex) { int v = Edgeco[i].v; dfs(v); f[u] = max(f[u], sum[u] + f[v]); } } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) scanf("%d", &val[i]); for(int i = 1; i <= m; i ++) { int u, v; scanf("%d%d", &u, &v); add(u, v); } for(int i = 1; i <= n; i ++) if(!color[i]) Tarjan(i); for(int i = 1; i <= n; i ++) for(int j = h[i]; j; j = Edge[j].nex) { int v = Edge[j].v; if (color[v] != color[i]) addco(color[i], color[v]); } int ans = 0; for(int i = 1; i <= cnt; i ++) if(!f[i]) { dfs(i); ans = max(ans, f[i]); } printf("%d", ans); return 0; }
然后最近看了一下之前校队选拔的题,好!难!怎么那么多DP数论,突然慌慌。但是巨巨学长说只要能做出来最简单的几道就能苟进队了,我!信!个!鬼!于是去水模板题了。