BZOJ 1179: [Apio2009]Atm


http://www.lydsy.com/JudgeOnline/problem.php?id=1179

强联通缩点,DAG DP

const int N = int(5e5) + 9;
VI _adj[N], adj[N]; int _bonus[N], bonus[N];
bool _isBar[N], isBar[N];
int _n, n;
int _st;


int dfn[N], low[N], bel[N], sta[N], Time, top; VI con[N];

#define v (*it)
void tarjan(int u){
    
    low[u] = dfn[u] = ++Time;
    sta[top++] = u;
    
    ECH(it, _adj[u]){
        if (dfn[v] < dfn[u]){
            if (!dfn[v]) tarjan(v);
            checkMin(low[u], low[v]);
        }
    }
    
    if (low[u] == dfn[u]){
        int t;
        do{
            t = sta[--top];
            con[n].PB(t);
            bel[t] = n;
            dfn[t] = INF;
            bonus[n] += _bonus[t];
            isBar[n] |= _isBar[t];
        } while(t != u);
        ++n;
    }
}


void scc(){
    
    REP_1(u, _n) if(!dfn[u]) tarjan(u);
    
    REP_1(u, _n) ECH(it, _adj[u]){
        int a = bel[u], b = bel[v];
        if (a == b) continue;
        adj[b].PB(a);
    }
}

int F[N]; int f(int u){
    int &res = F[u];
    if (res == -1){
        int t = -INF;
        ECH(it, adj[u]) checkMax(t, f(v));
        res = t >= 0 ? t + bonus[u] : -INF;
    }
    return res;
}

int main(){
    
#ifndef ONLINE_JUDGE
    freopen("/users/xiaodao/desktop/Exercise/in.txt", "r", stdin);
    //freopen("/users/xiaodao/desktop/Exercise/out.txt", "w", stdout);
#endif
    
    RD(_n); Rush{
        int a, b; RD(a, b); --a, --b;
        _adj[a].PB(b);
    }
    REP(i, _n) RD(_bonus[i]);
    --RD(_st); Rush _isBar[RD()-1] = true;
    
    scc();
    
    FLC(F, -1); int st = bel[_st]; F[st] = bonus[st];
    int z = 0; REP(i, n) if (isBar[i]) checkMax(z, f(i));
    
    /*REP(i, n){
        ECH(it, con[i]) cout << v << " ";
        cout << bonus[i] << endl;
    }*/
    
    cout << z << endl;
}