您的位置:首页 > 其它

bzoj1179 [Apio2009]Atm

2017-04-26 15:57 447 查看
传送门: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;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: