[APIO 2009] Atm

[题目链接]

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

[算法]

        首先 , 将这张图缩点 , 然后 , SPFA最长路即可

        时间复杂度 : O(KN)

[代码]

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500010
const int INF = 1e9;

struct edge
{
        int to , nxt;
} e[MAXN << 1] , ec[MAXN << 1];

int tot , n , m , timer , cnt , S , P;
int low[MAXN] , value[MAXN] , dfn[MAXN] , dist[MAXN] , heada[MAXN] , headb[MAXN] , belong[MAXN] , c[MAXN] , id[MAXN];
bool instack[MAXN] , inq[MAXN];
stack< int > s;

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline void addedgea(int u , int v)
{
        ++tot;
        e[tot] = (edge){v , heada[u]};
        heada[u] = tot;
}
inline void addedgeb(int u , int v)
{
        ++tot;
        ec[tot] = (edge){v , headb[u]};
        headb[u] = tot;
}
inline void tarjan(int u)
{
        low[u] = dfn[u] = ++timer;
        s.push(u);
        instack[u] = true;
        for (int i = heada[u]; i; i = e[i].nxt)
        {
                int v = e[i].to;
                if (!dfn[v])
                {
                        tarjan(v);
                        low[u] = min(low[u] , low[v]);        
                }    else if (instack[v]) low[u] = min(low[u] , dfn[v]);
        }
        if (dfn[u] == low[u])
        {
                ++cnt;
                int v;
                do
                {
                        v = s.top();
                        s.pop();
                        instack[v] = false;
                        belong[v] = cnt;
                        value[cnt] += c[v];
                }    while (v != u);
        }        
}
inline void spfa(int s)
{
        queue< int > q;
        for (int i = 1; i <= cnt; i++) 
        {
                dist[i] = 0;
                inq[i] = false;
        }
        dist[s] = value[s];
        q.push(s);
        inq[s] = true;
        while (!q.empty())
        {
                int cur = q.front();
                q.pop();
                inq[cur] = false;
                for (int i = headb[cur]; i; i = ec[i].nxt)
                {
                        int v = ec[i].to , w = value[v];
                        if (dist[cur] + w > dist[v])
                        {
                                dist[v] = dist[cur] + w;
                                if (!inq[v])
                                {
                                        inq[v] = true;
                                        q.push(v);
                                }
                        }
                }
         }
}

int main()
{
        
        read(n); read(m);
        for (int i = 1; i <= m; i++)
        {
                int x , y;
                read(x); read(y);
                addedgea(x , y);
        }
        for (int i = 1; i <= n; i++) read(c[i]);
        read(S); read(P);
        for (int i = 1; i <= P; i++) read(id[i]);
        for (int i = 1; i <= n; i++)
                if (!dfn[i]) tarjan(i);
        tot = 0;    
        for (int u = 1; u <= n; u++)
        {
                for (int i = heada[u]; i; i = e[i].nxt)
                {
                        int v = e[i].to;
                        if (belong[u] != belong[v])
                                addedgeb(belong[u] , belong[v]);
                }
        }
        spfa(belong[S]);
        int ans = 0;
        for (int i = 1; i <= P; i++) chkmax(ans , dist[belong[id[i]]]);
        printf("%d\n" , ans);
        
        return 0;
    
}

 

       

posted @ 2018-10-30 16:12  evenbao  阅读(166)  评论(0编辑  收藏  举报