• bzoj 1179


    题意:给你一个有向图,每个点有一个权值,有一个起点和q个终点,没经过一个点加上这个点的权值,让你选一条路,问你最大值是多少。

    思路:tarjan强连通缩个点, 然后在拓扑图上dp一下就好啦, 注意第二次建图建反向边会好一点。

      1 #include<bits/stdc++.h>
      2 #define LL long long
      3 #define fi first
      4 #define se second
      5 #define mk make_pair
      6 #define pii pair<int,int>
      7 
      8 using namespace std;
      9 
     10 const int N=5e5+7;
     11 const int M=1e4+7;
     12 const int inf=0x3f3f3f3f;
     13 const LL INF=0x3f3f3f3f3f3f3f3f;
     14 const int mod=1e9 + 7;
     15 
     16 struct edge {
     17     int from, to, nx;
     18 }e[N];
     19 bool bar[N], flag[N], in[N], ok[N];
     20 int n, m, tot, cnt, S, p, idx, top, head[N], a[N], sum[N], dfn[N], low[N], id[N], f[N], st[N];
     21 
     22 vector<int> edge[N];
     23 void add(int from, int to) {
     24     e[tot].from = from;
     25     e[tot].to = to;
     26     e[tot].nx = head[from];
     27     head[from] = tot++;
     28 }
     29 
     30 void tarjan(int u) {
     31     ++idx;
     32     dfn[u] = low[u] = idx;
     33     st[top++] = u; in[u] = true;
     34     for(int i = head[u]; ~i; i = e[i].nx) {
     35         int v = e[i].to;
     36         if(!dfn[v]) {
     37             tarjan(v);
     38             low[u] = min(low[u], low[v]);
     39         } else if(in[v]) {
     40             low[u] = min(low[u], dfn[v]);
     41         }
     42     }
     43     if(low[u] == dfn[u]) {
     44         cnt++;
     45         while(1) {
     46             int now = st[--top];
     47             in[now] = false;
     48             id[now] = cnt;
     49             if(now == u) break;
     50         }
     51     }
     52 }
     53 
     54 int dp(int u) {
     55     if(f[u] != -1) return f[u];
     56     f[u] = 0;
     57     for(int i = 0; i < edge[u].size(); i++) {
     58         int v = edge[u][i];
     59         int ret = dp(v);
     60         if(ok[v]) {
     61             ok[u] = true;
     62             f[u] = max(f[u], f[v]);
     63         }
     64     }
     65     if(!ok[u]) return f[u];
     66     return f[u] = f[u] + sum[u];
     67 }
     68 int main() {
     69     memset(head, -1, sizeof(head));
     70     memset(f, -1, sizeof(f));
     71     scanf("%d%d", &n, &m);
     72     for(int i = 1; i <= m; i++) {
     73         int from, to; scanf("%d%d", &from, &to);
     74         add(from, to);
     75     }
     76     for(int i = 1; i <= n; i++)
     77         scanf("%d", &a[i]);
     78 
     79     scanf("%d%d", &S, &p);
     80     for(int i = 1; i <= p; i++) {
     81         int x; scanf("%d", &x);
     82         flag[x] = true;
     83     }
     84     for(int i = 1; i <= n; i++) {
     85         if(!dfn[i]) tarjan(i);
     86     }
     87     for(int i = 1; i <= n; i++) {
     88         sum[id[i]] += a[i];
     89         bar[id[i]] |= flag[i];
     90     }
     91     for(int i = 0; i < tot; i++) {
     92         int u = e[i].from, v = e[i].to;
     93         if(id[u] != id[v]) {
     94             edge[id[v]].push_back(id[u]);
     95         }
     96     }
     97     S = id[S];
     98     ok[S] = true;
     99     int ans = 0;
    100     for(int i = 1; i <= cnt; i++) {
    101         if(bar[i]) {
    102             ans = max(ans, dp(i));
    103         }
    104     }
    105     printf("%d
    ", ans);
    106     return 0;
    107 }
    108 /*
    109 */
  • 相关阅读:
    进程间通信之数据共享--共享内存
    进程间通信之分工协作-信号灯
    进程间通信之分工协作--锁
    进程间通信之事件通知--信号
    进程间通信之数据传输--Socket
    c++模板特化
    DAG模型:嵌套矩形
    数字三角形
    c柔性数组结构成员
    模板
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9003694.html
Copyright © 2020-2023  润新知