感觉已经掌握了tarjan的真正思想。。
1 #include <cstdio> 2 using namespace std; 3 4 const int maxn=1e4+5, maxm=1e5+5; 5 6 inline int max(int a, int b) { return a<b?b:a; } 7 inline int min(int a, int b) { return a<b?a:b; } 8 9 class Graph{ 10 public: 11 struct Edge{ 12 Graph *belong; 13 int to, next; 14 Edge operator ++(){ *this=belong->edge[next]; return *this; } 15 int operator *(){ return to; } 16 }; 17 void addedge(int a, int b){ 18 Edge &e=edge[++cntedge]; 19 e.to=b, e.next=fir[a]; 20 fir[a]=cntedge, e.belong=this; 21 } 22 Edge gete(int x) { return edge[fir[x]]; } 23 Edge edge[maxm]; 24 private: 25 int cntedge, fir[maxn]; 26 }; 27 28 int n, m, tail, time, cntscc, ans; 29 int v[maxn], dfn[maxn], low[maxn]; 30 int stack[maxn], instack[maxn]; 31 int belong[maxn], in[maxn], v_scc[maxn], dp[maxn]; 32 Graph g, g_scc; 33 34 void tarjan(int now){ 35 dfn[now]=low[now]=++time; 36 stack[++tail]=now, instack[now]=1; 37 int nowson; 38 for (Graph::Edge e=g.gete(now); *e; ++e){ 39 nowson=*e; 40 //写在前面比较好,尽管无伤大雅 41 if (instack[nowson]) 42 low[now]=min(low[now], dfn[nowson]); 43 if (!dfn[nowson]){ 44 tarjan(nowson); 45 low[now]=min(low[now], low[nowson]); 46 } 47 } 48 if (dfn[now]==low[now]){ 49 ++cntscc; 50 for (; low[stack[tail]]!=dfn[stack[tail]]; --tail){ 51 instack[stack[tail]]=0; //这里忘记了!! 52 belong[stack[tail]]=cntscc; 53 v_scc[cntscc]+=v[stack[tail]]; 54 } 55 instack[stack[tail]]=0; 56 belong[stack[tail]]=cntscc; 57 v_scc[cntscc]+=v[stack[tail]]; 58 --tail; 59 } 60 } 61 62 void dfs(int now, int par){ 63 int nowson; 64 for (Graph::Edge e=g_scc.gete(now); *e; ++e){ 65 nowson=*e; 66 if (nowson==par) continue; 67 if (!dp[nowson]) dfs(nowson, now); 68 dp[now]=max(dp[now], dp[nowson]); 69 } 70 dp[now]+=v_scc[now]; 71 ans=max(ans, dp[now]); 72 } 73 74 int main(){ 75 scanf("%d%d", &n, &m); 76 for (int i=1; i<=n; ++i) scanf("%d", &v[i]); 77 int x, y; 78 for (int i=0; i<m; ++i){ scanf("%d%d", &x, &y); g.addedge(x, y); } 79 for (int i=1; i<=n; ++i) 80 if (!dfn[i]) tarjan(i); 81 for (int i=1; i<=n; ++i) 82 for (Graph::Edge e=g.gete(i); *e; ++e){ 83 if (belong[i]!=belong[*e]){ 84 g_scc.addedge(belong[i], belong[*e]); 85 ++in[belong[*e]]; 86 } 87 } 88 for (int i=1; i<=cntscc; ++i) 89 if (!in[i]) dfs(i, 0); 90 printf("%d ", ans); 91 }