poj 1459 Power Network 多源多汇网络流

题目链接:http://poj.org/problem?id=1459

题意:

总共有N个点,M条边,有np个点是加油站即源点,有nc个点是消耗点,即汇点。

给出M条边的容量,每个源点最大的流出量和每个汇点的最大流入量。

求最多可以消耗多少。

思路:

多源多汇网络流就是增加一个超级源点和超级汇点。

把超级源点向每个源点连一条边,容量为该源点流出的最大量。

把每个汇点向超级汇点连一条边,容量为该汇点规定的最大流入量。

然后求最大流。

  1 //#include <bits/stdc++.h>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <vector>
  6 #include <queue>
  7 using namespace std;
  8 int n, m, s, t;
  9 #define maxn 110
 10 #define inf 0x3f3f3f3f
 11 struct Edge
 12 {
 13     int from, to, cap, flow;
 14     Edge(int f, int t, int c, int fl)
 15     {
 16         from = f; to = t; cap = c; flow = fl;
 17     }
 18 };
 19 vector <Edge> edges;
 20 vector <int> G[maxn];
 21 int d[maxn], vis[maxn], cur[maxn];
 22 void AddEdge(int from, int to, int cap)
 23 {
 24     edges.push_back(Edge(from, to, cap, 0));
 25     edges.push_back(Edge(to, from, 0, 0));
 26     m = edges.size();
 27     G[from].push_back(m-2);
 28     G[to].push_back(m-1);
 29 }
 30 bool bfs()
 31 {
 32     memset(vis, 0, sizeof(vis));
 33     d[s] = 0;
 34     vis[s] = 1;
 35     queue <int> q;
 36     q.push(s);
 37     while(!q.empty())
 38     {
 39         int x = q.front(); q.pop();
 40         for(int i = 0; i < G[x].size(); i++)
 41         {
 42             Edge &e = edges[G[x][i]];
 43             if(!vis[e.to] && e.cap > e.flow)
 44             {
 45                 d[e.to] = d[x] + 1;
 46                 vis[e.to] = 1;
 47                 q.push(e.to);
 48             }
 49         }
 50     }
 51     return vis[t];
 52 }
 53 int dfs(int x, int a)
 54 {
 55     if(x == t || a == 0) return a;
 56     int flow = 0, f;
 57     for(int &i = cur[x]; i < G[x].size(); i++)
 58     {
 59         Edge &e = edges[G[x][i]];
 60         if(d[e.to] == d[x] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0)
 61         {
 62             e.flow += f;
 63             edges[G[x][i]^1].flow -= f;
 64             flow += f;
 65             a -= f;
 66             if(a == 0) break;
 67         }
 68     }
 69     return flow;
 70 }
 71 int maxflow()
 72 {
 73     int flow = 0;
 74     while(bfs())
 75     {
 76         memset(cur, 0, sizeof(cur));
 77         flow += dfs(s, inf);
 78     }
 79     return flow;
 80 }
 81 int N, np, nc, M;
 82 int main() 
 83 {
 84     //freopen("in.txt", "r", stdin);
 85     //freopen("out.txt", "w", stdout);
 86     while(~scanf("%d%d%d%d", &N, &np, &nc, &M))
 87     {
 88         edges.clear();
 89         for(int i = 0; i <= N+1; i++) G[i].clear();
 90         int a, b, c; char op;
 91         for(int i = 1; i <= M; i++)
 92         {
 93             cin>>op; scanf("%d", &a); 
 94             cin>>op; scanf("%d", &b);
 95             cin>>op; scanf("%d", &c);
 96             AddEdge(a, b, c);
 97         }
 98         s = N; t = N+1;
 99         for(int i = 1; i <= np; i++)
100         {
101             cin>>op; scanf("%d", &a);
102             cin>>op; scanf("%d", &c);
103             AddEdge(s, a, c);
104         }
105         for(int i = 1; i <= nc; i++)
106         {
107              cin>>op; scanf("%d", &a);
108              cin>>op; scanf("%d", &c);
109              AddEdge(a, t, c);
110         }
111         n = N+2;
112         int flow = maxflow();
113         printf("%d\n", flow);
114     }
115     return 0;
116 }

 

posted @ 2016-02-25 20:50  下周LGD该赢了吧  阅读(508)  评论(0编辑  收藏  举报