• [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
    " , ans);
            
            return 0;
        
    }

           

  • 相关阅读:
    移动端按钮居底
    easyui用KindEditor编辑器
    查找数组中与后面项匹配的和猴子选大王
    before和after的样式符号
    jq的select
    验证最多2位小数,1到10 不超过10 带两位小数的正则表达式
    在谷歌浏览器下vue的@input事件问题
    mvc项目+vue+vant【进行中】
    微商代理查询系统 开发完成,免费体验试用哦!
    淘宝出了个麻吉宝区块连产品,附带麻吉宝邀请码!
  • 原文地址:https://www.cnblogs.com/evenbao/p/9877490.html
Copyright © 2020-2023  润新知