您的位置:首页 > 理论基础 > 计算机网络

poj 1459 Power Network 多源多汇网络流

2016-02-25 20:50 567 查看
题目链接:http://poj.org/problem?id=1459

题意:

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

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

求最多可以消耗多少。

思路:

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

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

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

然后求最大流。

//#include <bits/stdc++.h>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
int n, m, s, t;
#define maxn 110
#define inf 0x3f3f3f3f
struct Edge
{
int from, to, cap, flow;
Edge(int f, int t, int c, int fl)
{
from = f; to = t; cap = c; flow = fl;
}
};
vector <Edge> edges;
vector <int> G[maxn];
int d[maxn], vis[maxn], cur[maxn];
void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to, from, 0, 0));
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool bfs()
{
memset(vis, 0, sizeof(vis));
d[s] = 0;
vis[s] = 1;
queue <int> q;
q.push(s);
while(!q.empty())
{
int x = q.front(); q.pop();
for(int i = 0; i < G[x].size(); i++)
{
Edge &e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow)
{
d[e.to] = d[x] + 1;
vis[e.to] = 1;
q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int x, int a)
{
if(x == t || a == 0) return a;
int flow = 0, f;
for(int &i = cur[x]; i < G[x].size(); i++)
{
Edge &e = edges[G[x][i]];
if(d[e.to] == d[x] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0)
{
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
int maxflow()
{
int flow = 0;
while(bfs())
{
memset(cur, 0, sizeof(cur));
flow += dfs(s, inf);
}
return flow;
}
int N, np, nc, M;
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
while(~scanf("%d%d%d%d", &N, &np, &nc, &M))
{
edges.clear();
for(int i = 0; i <= N+1; i++) G[i].clear();
int a, b, c; char op;
for(int i = 1; i <= M; i++)
{
cin>>op; scanf("%d", &a);
cin>>op; scanf("%d", &b);
cin>>op; scanf("%d", &c);
AddEdge(a, b, c);
}
s = N; t = N+1;
for(int i = 1; i <= np; i++)
{
cin>>op; scanf("%d", &a);
cin>>op; scanf("%d", &c);
AddEdge(s, a, c);
}
for(int i = 1; i <= nc; i++)
{
cin>>op; scanf("%d", &a);
cin>>op; scanf("%d", &c);
AddEdge(a, t, c);
}
n = N+2;
int flow = maxflow();
printf("%d\n", flow);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: