• 洛谷P2050 美食节


    修车加强版。发现每个厨师拆成p个点太浪费了,毕竟总共用到的才p个点。于是从下往上一个一个加,加到满流就停。

    论动态加点费用流的正确姿势......

    我自己加总是出现负环...我是每次加一整层,然后跑完这一层再加下一层,这样会显而易见的出现负环......

    然后我们发现如果每增广一流量就加边就不会出现这种毒瘤现象,因为每次加的一定比增广的劣......

    注意一定要动态开点,不能只用一个点代表厨师。否则可能出现厨师的第一次给了多个菜的情况...

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 100010, INF = 0x7f7f7f7f;
      4 
      5 struct Edge {
      6     int nex, v, c, len;
      7     Edge(int Nex = 0, int V = 0, int C = 0, int Len = 0) {
      8         nex = Nex;
      9         v = V;
     10         c = C;
     11         len = Len;
     12     }
     13 }edge[5000010]; int tp = 1;
     14 
     15 int e[N], lm, now[N], pre[N], flow[N], p[N], cnt[N], d[N];
     16 int val[110][110];
     17 bool vis[N];
     18 std::queue<int> Q;
     19 
     20 inline void add(int x, int y, int z, int w) {
     21     edge[++tp] = Edge(e[x], y, z, w);
     22     e[x] = tp;
     23     edge[++tp] = Edge(e[y], x, 0, -w);
     24     e[y] = tp;
     25     return;
     26 }
     27 
     28 inline bool SPFA(int s, int t) {
     29     memset(d + 1, 0x7f, lm * sizeof(int));
     30     vis[s] = 1;
     31     flow[s] = INF;
     32     d[s] = 0;
     33     Q.push(s);
     34     while(!Q.empty()) {
     35         int x = Q.front();
     36         Q.pop();
     37         vis[x] = 0;
     38         for(int i = e[x]; i; i = edge[i].nex) {
     39             int y = edge[i].v;
     40             if(d[y] > d[x] + edge[i].len && edge[i].c) {
     41                 d[y] = d[x] + edge[i].len;
     42                 //printf("%d -> %d 
    ", x, y);
     43                 flow[y] = std::min(flow[x], edge[i].c);
     44                 pre[y] = i;
     45                 if(!vis[y]) {
     46                     vis[y] = 1;
     47                     Q.push(y);
     48                 }
     49             }
     50         }
     51     }
     52     return d[t] < INF;
     53 }
     54 
     55 inline void update(int s, int t) {
     56     int f = flow[t];
     57     while(t != s) {
     58         int i = pre[t];
     59         edge[i].c -= f;
     60         edge[i ^ 1].c += f;
     61         t = edge[i ^ 1].v;
     62     }
     63     return;
     64 }
     65 
     66 int main() {
     67 
     68     int n, m, tot = 0;
     69     scanf("%d%d", &n, &m);
     70     lm = n;
     71     int s = ++lm;
     72     int t = ++lm;
     73     for(int i = 1; i <= n; i++) {
     74         scanf("%d", &p[i]);
     75         add(s, i, p[i], 0);
     76         tot += p[i];
     77     }
     78     for(int i = 1; i <= n; i++) {
     79         for(int j = 1; j <= m; j++) {
     80             scanf("%d", &val[i][j]);
     81         }
     82     }
     83     /// sol
     84     for(int i = 1; i <= m; i++) {
     85         add(++lm, t, 1, 0);
     86         cnt[i] = 1;
     87         now[i] = tp - 1;
     88         for(int j = 1; j <= n; j++) {
     89             add(j, lm, 1, val[j][i]);
     90         }
     91     }
     92 
     93     int ans = 0;
     94     while(tot) {
     95         //printf("tot = %d ans = %d 
    ", tot, ans);
     96         SPFA(s, t);
     97         ans += d[t] * flow[t];
     98         tot -= flow[t];
     99         update(s, t);
    100         for(int j = 1; j <= m; j++) {
    101             if(edge[now[j]].c) continue;
    102             add(++lm, t, 1, 0);
    103             now[j] = tp - 1;
    104             cnt[j]++;
    105             for(int i = 1; i <= n; i++) {
    106                 add(i, lm, 1, cnt[j] * val[i][j]);
    107             }
    108             break;
    109         }
    110     }
    111 
    112     printf("%d
    ", ans);
    113     return 0;
    114 }
    AC代码
  • 相关阅读:
    codeforces 439C 模拟
    codeforces 435B
    【WebVR】AFrame中的A-sky无法利用src指定路径显示全景图
    【UE4】添加头文件之后VS中UCLASS()报错问题解决办法
    【UE4】蓝图之间的通讯
    git中报unable to auto-detect email address 错误的解决办法
    2017ACM省赛总结与生涯回顾
    hihocoder#1121 : 二分图一•二分图判定
    hihocoder#1039 : 字符消除
    2048low版
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10573573.html
Copyright © 2020-2023  润新知