• 洛谷P2469 星际竞速


    上下界费用流比较无脑,提供一种更巧妙的费用流,无需上下界。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <queue>
      4 #include <cstring>
      5 
      6 const int N = 1610, 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];
     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, m;
     82     scanf("%d%d", &n, &m);
     83     int s = n * 2 + 1;
     84     int t = s + 1, S = s + 3, T = s + 4, O = s + 5;
     85     for(int i = 1, x; i <= n; i++) {
     86         scanf("%d", &x);
     87         add(O, i, 1, x);
     88         add(i + n, O, INF, 0);
     89         // add(i, i + n, 1, 0);
     90         add(S, i + n, 1, 0);
     91         add(i, T, 1, 0);
     92         add(i + n, t, 1, 0);
     93     }
     94     add(s, O, 1, 0);
     95     for(int i = 1, x, y, z; i <= m; i++) {
     96         scanf("%d%d%d", &x, &y, &z);
     97         if(x > y) {
     98             std::swap(x, y);
     99         }
    100         add(x + n, y, INF, z);
    101     }
    102     add(t, s, INF, 0);
    103 
    104     int ans;
    105     solve(S, T, ans);
    106     printf("%d", ans);
    107     return 0;
    108 }
    上下界费用流AC代码
  • 相关阅读:
    闲谈系列之一——数据库主键GUID
    一个简单通用权限管理系统,求各位帮忙看看
    php 计算指定年份的周总数与及第几周的开始日期和结束日期(从周一开始)
    创建虚拟机流程详细过程链接
    阿里云CDN加速设置
    sublime Text3 快捷键
    Linux命令(centos7)
    分布式数据库
    mysql 分区和分表
    Linux crontab 命令格式与详细例子
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10116671.html
Copyright © 2020-2023  润新知