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;
}
View Code

 

posted @ 2017-04-26 15:57  Galaxies  阅读(185)  评论(0编辑  收藏  举报