• [BZOJ1179] [Apio2009]Atm(tarjan缩点 + spfa)


    传送门

    题意

    N个点M条边的有向图

    每个点有点权

    从某一个结点出发

    问能获得的最大点权和

    一个点的点权最多被计算一次

    N<=500000 M<=500000

    思路

    先tarjan缩点,然后就形成一个dag,无环,所以直接spfa求最长路就行。

    也可以先缩点,然后拓扑排序 + dp 搞。

    代码

      1 #include <map>
      2 #include <queue>
      3 #include <stack>
      4 #include <cstdio>
      5 #include <cstring>
      6 #include <iostream>
      7 
      8 const int MAXN = 500001;
      9 int n, m, s, p, cnt, cnt1, tim, sz, ans;
     10 int head[MAXN], to[MAXN], next[MAXN], head1[MAXN], to1[MAXN], next1[MAXN];
     11 int a[MAXN], dfn[MAXN], low[MAXN], belong[MAXN], val[MAXN], dis[MAXN];
     12 bool ins[MAXN], vis[MAXN];
     13 std::map <int, int> map1[MAXN];
     14 std::stack <int> S;
     15 std::queue <int> q;
     16 
     17 inline int max(int x, int y)
     18 {
     19     return x > y ? x : y;
     20 }
     21 
     22 inline int min(int x, int y)
     23 {
     24     return x < y ? x : y;
     25 }
     26 
     27 inline int read()
     28 {
     29     int f = 1, x = 0;
     30     char ch = getchar();
     31     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
     32     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
     33     return f * x;
     34 }
     35 
     36 inline void add(int x, int y)
     37 {
     38     to[cnt] = y;
     39     next[cnt] = head[x];
     40     head[x] = cnt++;
     41 }
     42 
     43 inline void add1(int x, int y)
     44 {
     45     to1[cnt1] = y;
     46     next1[cnt1] = head1[x];
     47     head1[x] = cnt1++;
     48 }
     49 
     50 inline void dfs(int u)
     51 {
     52     int i, v;
     53     S.push(u);
     54     ins[u] = 1;
     55     dfn[u] = low[u] = ++tim;
     56     for(i = head[u]; i ^ -1; i = next[i])
     57     {
     58         v = to[i];
     59         if(!dfn[v])
     60         {
     61             dfs(v);
     62             low[u] = min(low[u], low[v]);
     63         }
     64         else if(ins[v]) low[u] = min(low[u], dfn[v]);
     65     }
     66     if(!(low[u] ^ dfn[u]))
     67     {
     68         sz++;
     69         do
     70         {
     71             v = S.top();
     72             S.pop();
     73             belong[v] = sz;
     74             ins[v] = 0;
     75         }
     76         while(u ^ v);
     77     }
     78 }
     79 
     80 inline void spfa()
     81 {
     82     int i, u, v;
     83     dis[belong[s]] = val[belong[s]];
     84     q.push(belong[s]);
     85     vis[belong[s]] = 1;
     86     while(!q.empty())
     87     {
     88         u = q.front();
     89         q.pop();
     90         vis[u] = 0;
     91         for(i = head1[u]; i ^ -1; i = next1[i])
     92         {
     93             v = to1[i];
     94             if(dis[v] < dis[u] + val[v])
     95             {
     96                 dis[v] = dis[u] + val[v];
     97                 if(!vis[v])
     98                 {
     99                     vis[v] = 1;
    100                     q.push(v);
    101                 }
    102             }
    103         }
    104     }
    105 }
    106 
    107 int main()
    108 {
    109     int i, x, y, u, v;
    110     n = read();
    111     m = read();
    112     memset(head, -1, sizeof(head));
    113     memset(head1, -1, sizeof(head1));
    114     for(i = 1; i <= m; i++)
    115     {
    116         x = read();
    117         y = read();
    118         add(x, y);
    119     }
    120     for(i = 1; i <= n; i++) a[i] = read();
    121     s = read();
    122     p = read();
    123     dfs(s);
    124     for(i = 1; i <= n; i++) val[belong[i]] += a[i];
    125     for(u = 1; u <= n; u++)
    126         for(i = head[u]; i ^ -1; i = next[i])
    127         {
    128             v = to[i];
    129             if(belong[u] ^ belong[v] && !map1[belong[u]][belong[v]])
    130                 map1[belong[u]][belong[v]] = 1, add1(belong[u], belong[v]);
    131         }
    132     spfa();
    133     for(i = 1; i <= p; i++)
    134     {
    135         x = read();
    136         ans = max(ans, dis[belong[x]]);
    137     }
    138     printf("%d
    ", ans);
    139     return 0;
    140 }
    View Code
     
  • 相关阅读:
    HTML & CSS
    Python面向对象编程
    Python 内置函数
    Python函数
    三.python高级
    使用loadrunner编写webservice接口请求
    loadrunner中JavaVuser脚本的编写
    loadrunner 参数化取值方式详解
    loadrunner 参数化-如何从数据库中取数据-连接数据库进行参数化
    vmstat命令参数介绍
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6858372.html
Copyright © 2020-2023  润新知