zoukankan      html  css  js  c++  java
  • 洛谷P4043 支线剧情

    题意:给定DAG,通过每条边需要时间。

    从某号点回到1号点不需要时间。

    从1号点出发,求最少要多久才能走完所有边。

    解:

    有源汇有上下界最小费用可行流。

    直接连边,费用为时间,下界为1,无上界。

    每个点都可能是终点,往t连边。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <queue>
      4 #include <cstring>
      5 
      6 const int N = 310, M = 1000010, INF = 0x3f3f3f3f;
      7 
      8 struct Edge {
      9     int nex, v, c, len;
     10 }edge[M << 1]; int top = 1;
     11 
     12 int e[N], d[N], vis[N], pre[N], flow[N], ot[N];
     13 std::queue<int> Q;
     14 
     15 inline void add(int x, int y, int z, int w) {
     16     top++;
     17     edge[top].v = y;
     18     edge[top].c = z;
     19     edge[top].len = w;
     20     edge[top].nex = e[x];
     21     e[x] = top;
     22 
     23     top++;
     24     edge[top].v = x;
     25     edge[top].c = 0;
     26     edge[top].len = -w;
     27     edge[top].nex = e[y];
     28     e[y] = top;
     29     return;
     30 }
     31 
     32 inline bool SPFA(int s, int t) {
     33     memset(d, 0x3f, sizeof(d));
     34     d[s] = 0;
     35     flow[s] = INF;
     36     vis[s] = 1;
     37     Q.push(s);
     38     while(!Q.empty()) {
     39         int x = Q.front();
     40         Q.pop();
     41         vis[x] = 0;
     42         for(int i = e[x]; i; i = edge[i].nex) {
     43             int y = edge[i].v;
     44             if(edge[i].c && d[y] > d[x] + edge[i].len) {
     45                 d[y] = d[x] + edge[i].len;
     46                 pre[y] = i;
     47                 flow[y] = std::min(flow[x], edge[i].c);
     48                 if(!vis[y]) {
     49                     vis[y] = 1;
     50                     Q.push(y);
     51                 }
     52             }
     53         }
     54     }
     55     return d[t] < INF;
     56 }
     57 
     58 inline void update(int s, int t) {
     59     int temp = flow[t];
     60     while(t != s) {
     61         int i = pre[t];
     62         edge[i].c -= temp;
     63         edge[i ^ 1].c += temp;
     64         t = edge[i ^ 1].v;
     65     }
     66     return;
     67 }
     68 
     69 inline int solve(int s, int t, int &cost) {
     70     int ans = 0;
     71     cost = 0;
     72     while(SPFA(s, t)) {
     73         ans += flow[t];
     74         cost += flow[t] * d[t];
     75         update(s, t);
     76     }
     77     return ans;
     78 }
     79 
     80 int main() {
     81     int n, cost = 0;
     82     scanf("%d", &n);
     83     int ss = n + 1, tt = n + 2, t = n + 3;
     84     for(int i = 1, x, y, z; i <= n; i++) {
     85         scanf("%d", &x);
     86         for(int j = 1; j <= x; j++) {
     87             scanf("%d%d", &y, &z);
     88             // i -> y    z
     89             add(i, y, INF, z);
     90             ot[i]++;
     91             ot[y]--;
     92             cost += z;
     93         }
     94         add(i, t, INF, 0);
     95     }
     96     for(int i = 1; i <= n; i++) {
     97         if(ot[i] > 0) {
     98             add(i, tt, ot[i], 0);
     99         }
    100         else {
    101             add(ss, i, -ot[i], 0);
    102         }
    103     }
    104     add(t, 1, INF, 0);
    105     int ans;
    106     solve(ss, tt, ans);
    107     printf("%d", ans + cost);
    108     return 0;
    109 }
    AC代码
  • 相关阅读:
    POJ 2739 Sum of Consecutive Prime Numbers( *【素数存表】+暴力枚举 )
    Hihocoder #1098 : 最小生成树二·Kruskal算法 ( *【模板】 )
    POJ 1861 Network (Kruskal算法+输出的最小生成树里最长的边==最后加入生成树的边权 *【模板】)
    java
    游戏源码--Unity开源Moba游戏-服务器-客户端完整V1.0
    c# 跨平台ide JetBrains Rider
    lua-遍历集合-ipairs和pairs的区别
    Mixamo Fuse10分钟创建角色
    现学现卖】IntelliJ+EmmyLua 开发调试Unity中Xlua
    params传递任意参数
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10102073.html
Copyright © 2011-2022 走看看