[CODEVS1915] 分配问题(最小费用最大流)

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CODEVS1915] 分配问题(最小费用最大流)相关的知识,希望对你有一定的参考价值。

传送门

 

脑残题

建图都懒得说了

 

——代码

技术分享
  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #define N 1000001
  6 #define min(x, y) ((x) < (y) ? (x) : (y))
  7 
  8 int n, cnt, s, t;
  9 int a[101][101], dis[N], pre[N];
 10 int head[N], to[N << 1], val[N << 1], cost[N << 1], next[N << 1];
 11 bool vis[N];
 12 
 13 inline int read()
 14 {
 15     int x = 0, f = 1;
 16     char ch = getchar();
 17     for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1;
 18     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0;
 19     return x * f;
 20 }
 21 
 22 inline void add(int x, int y, int z, int c)
 23 {
 24     to[cnt] = y;
 25     val[cnt] = z;
 26     cost[cnt] = c;
 27     next[cnt] = head[x];
 28     head[x] = cnt++;
 29 }
 30 
 31 inline bool spfa()
 32 {
 33     int i, u, v;
 34     std::queue <int> q;
 35     memset(vis, 0, sizeof(vis));
 36     memset(pre, -1, sizeof(pre));
 37     memset(dis, 127 / 3, sizeof(dis));
 38     q.push(s);
 39     dis[s] = 0;
 40     while(!q.empty())
 41     {
 42         u = q.front(), q.pop();
 43         vis[u] = 0;
 44         for(i = head[u]; i ^ -1; i = next[i])
 45         {
 46             v = to[i];
 47             if(val[i] && dis[v] > dis[u] + cost[i])
 48             {
 49                 dis[v] = dis[u] + cost[i];
 50                 pre[v] = i;
 51                 if(!vis[v])
 52                 {
 53                     q.push(v);
 54                     vis[v] = 1;
 55                 }
 56             }
 57         }
 58     }
 59     return pre[t] ^ -1;
 60 }
 61 
 62 inline int dinic()
 63 {
 64     int i, d, sum = 0;
 65     while(spfa())
 66     {
 67         d = 1e9;
 68         for(i = pre[t]; i ^ -1; i = pre[to[i ^ 1]]) d = min(d, val[i]);
 69         for(i = pre[t]; i ^ -1; i = pre[to[i ^ 1]])
 70         {
 71             val[i] -= d;
 72             val[i ^ 1] += d;
 73         }
 74         sum += dis[t] * d;
 75     }
 76     return sum;
 77 }
 78 
 79 int main()
 80 {
 81     int i, j, x;
 82     n = read();
 83     s = 0, t = n + n + 1;
 84     memset(head, -1, sizeof(head));
 85     for(i = 1; i <= n; i++)
 86     {
 87         add(s, i, 1, 0);
 88         add(i, s, 0, 0);
 89         add(i + n, t, 1, 0);
 90         add(t, i + n, 0, 0);
 91         for(j = 1; j <= n; j++)
 92         {
 93             a[i][j] = read();
 94             add(i, j + n, 1, a[i][j]);
 95             add(j + n, i, 0, -a[i][j]);
 96         }
 97     }
 98     printf("%d\n", dinic());
 99     cnt = 0;
100     memset(head, -1, sizeof(head));
101     for(i = 1; i <= n; i++)
102     {
103         add(s, i, 1, 0);
104         add(i, s, 0, 0);
105         add(i + n, t, 1, 0);
106         add(t, i + n, 0, 0);
107         for(j = 1; j <= n; j++)
108         {
109             add(i, j + n, 1, -a[i][j]);
110             add(j + n, i, 0, a[i][j]);
111         }
112     }
113     printf("%d\n", -dinic());
114     return 0;
115 }
View Code

 

以上是关于[CODEVS1915] 分配问题(最小费用最大流)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P4014 分配问题 最小费用最大流+最大费用最大流

[网络流24题(5/24)] 分配问题(最小费用最大流)

P4014 分配问题(网络流24题 最大最小费用流)

Codevs1033蚯蚓的游戏问题-费用流

最小费用最大流

[网络流24题]运输问题