POJ 1459 最大流 第二题

http://poj.org/problem?id=1459

也是网络流的基础,只是虚拟出一个源点和终点,对应的生产值和消费值就加到与源点和终点的边上,然后做一次bfs就好了。

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <queue>
  4 #include <algorithm>
  5 #define INF 999999999
  6 //#define OPEN_FILE
  7 using namespace std;
  8 
  9 const int MAXN = 105;
 10 int cap[MAXN][MAXN], flow[MAXN][MAXN], p[MAXN], c[MAXN], f[MAXN];
 11 int n, ans;
 12 
 13 void get_cap(char s[])
 14 {
 15     int i, u, v, w;
 16     u = 0;
 17     for (i = 1; s[i] != ','; i++){
 18         u = u * 10 + (s[i] - '0');
 19     }
 20     v = 0;
 21     for (++i; s[i] != ')'; i++){
 22         v = v * 10 + (s[i] - '0');
 23     }
 24     int len = strlen(s);
 25     w = 0;
 26     for (++i; i < len; i++){
 27         w = w * 10 + (s[i] - '0');
 28     }
 29     cap[u][v] = w;
 30 }
 31 
 32 void get_pc(char s[], int* t, int o)
 33 {
 34     int i, u, w;
 35     u = 0;
 36     for (i = 1; s[i] != ')'; i++){
 37         u = u * 10 + (s[i] - '0');
 38     }
 39     int len = strlen(s);
 40     w = 0;
 41     for (++i; i < len; i++){
 42         w = w * 10 + (s[i] - '0');
 43     }
 44     if (o){
 45         cap[n][u] = w;
 46     }
 47     else{
 48         cap[u][n + 1] = w;
 49     }
 50     
 51 }
 52 
 53 void ek_bfs(){
 54     queue<int> d;
 55     int s, t, u, v;
 56     int a[MAXN];
 57     s = n;
 58     t = n + 1;
 59     ans = 0;
 60     while (1){
 61         memset(a, 0, sizeof(a));
 62         a[s] = INF;
 63         d.push(s);
 64         while (!d.empty()){
 65             u = d.front();
 66             d.pop();
 67             for (v = 0; v <= n + 1; v++){
 68                 if (a[v] || cap[u][v] <= flow[u][v]) continue;
 69                 f[v] = u;
 70                 d.push(v);
 71                 a[v] = min(a[u] , cap[u][v] - flow[u][v]);
 72             }
 73         }
 74         if (a[t] == 0) break;
 75         for (u = t; u != s; u = f[u]){
 76             flow[f[u]][u] += a[t];
 77             flow[u][f[u]] -= a[t];
 78         }
 79         ans += a[t];
 80     }
 81 }
 82 
 83 int main()
 84 {
 85 #ifdef OPEN_FILE
 86     freopen("in.txt", "r", stdin);
 87     freopen("out.txt", "w", stdout);
 88 #endif // OPEN_FILE
 89     int m, np, nc, i, j;
 90     char s[101];
 91     while (~scanf("%d%d%d%d", &n, &np, &nc, &m)){
 92         memset(cap, 0, sizeof(cap));
 93         memset(flow, 0, sizeof(flow));
 94         memset(p, 0, sizeof(p));
 95         memset(c, 0, sizeof(c));
 96         for (i = 1; i <= m; i++){
 97             scanf("%s", s);
 98             get_cap(s);
 99         }
100         for (i = 1; i <= np; i++){
101             scanf("%s", s);
102             get_pc(s, p, 1);
103         }
104         for (i = 1; i <= nc; i++){
105             scanf("%s", s);
106             get_pc(s, c, 0);
107         }
108         ek_bfs();
109         printf("%d\n", ans);
110     }
111 }
View Code

 

转载于:https://www.cnblogs.com/macinchang/p/4452253.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值