bzoj1179 [Apio2009]Atm
Posted 逢山开路 遇水架桥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1179 [Apio2009]Atm相关的知识,希望对你有一定的参考价值。
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1179
【题解】
tarjan缩强联通分量然后直接spfa上就行啦!
好久没写得这么畅快一遍过了qwq
# include <queue> # include <stdio.h> # include <string.h> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 1e6 + 10; const int mod = 1e9+7; # define RG register # define ST static int n, m, cn; int w[M], v[M]; int S; bool cup[M], c[M]; struct Graph { int n, m, head[M], nxt[M], to[M], tot; inline void set(int _n, int _m) { n = _n, m = _m; tot = 0; memset(head, 0, sizeof head); } inline void add(int u, int v) { ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; } }T, G; int dfn[M], DFN, low[M], scc, belong[M], st[M], stn; bool ins[M]; inline void tarjan(int x) { dfn[x] = low[x] = ++DFN; st[++stn] = x; ins[x] = 1; for (int i=T.head[x]; i; i=T.nxt[i]) { int y = T.to[i]; if(!dfn[y]) { tarjan(y); low[x] = min(low[x], low[y]); } else if(ins[y]) low[x] = min(low[x], dfn[y]); } if(dfn[x] == low[x]) { int t = 0; ++scc; while(t != x) { t = st[stn]; --stn; belong[t] = scc; ins[t] = 0; } } } inline void rebuild() { G.set(scc, m); for (int x=1; x<=n; ++x) for (int i=T.head[x]; i; i=T.nxt[i]) { int y = T.to[i]; if(belong[x] == belong[y]) continue; G.add(belong[x], belong[y]); } for (int x=1; x<=n; ++x) { if(cup[x]) c[belong[x]] = 1; v[belong[x]] += w[x]; } } int d[M]; bool vis[M]; inline void spfa() { queue<int> q; while(!q.empty()) q.pop(); for (int i=1; i<=scc; ++i) d[i]=0, vis[i]=0; q.push(belong[S]); vis[belong[S]] = 1; d[belong[S]] = v[belong[S]]; while(!q.empty()) { int top = q.front(); q.pop(); vis[top] = 0; for (int i=G.head[top]; i; i=G.nxt[i]) { int y = G.to[i]; if(d[y] < d[top]+v[y]) { d[y] = d[top]+v[y]; if(!vis[y]) { q.push(y); vis[y] = 1; } } } } } int main() { scanf("%d%d", &n, &m); T.set(n, m); for (int i=1; i<=m; ++i) { int u, v; scanf("%d%d", &u, &v); T.add(u, v); } for (int i=1; i<=n; ++i) scanf("%d", w+i); scanf("%d%d", &S, &cn); for (int i=1; i<=cn; ++i) { int u; scanf("%d", &u); cup[u] = 1; } scc = DFN = stn = 0; for (int i=1; i<=n; ++i) if(!dfn[i]) tarjan(i); rebuild(); spfa(); int ans = 0; for (int i=1; i<=scc; ++i) if(c[i]) ans = max(ans, d[i]); printf("%d\n", ans); return 0; }
以上是关于bzoj1179 [Apio2009]Atm的主要内容,如果未能解决你的问题,请参考以下文章