题目大意:网络流当中的多源多汇求最大流;
题目解析:生成一个超级源,指向所有源,并且生成一个超级汇,使得所有汇都指向超级汇;
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int inf=0x3fffffff;
const int maxn=110;
int n;
int map[maxn][maxn];
bool visited[maxn];
int pre[maxn];
int bfs(int start,int end)
{
queue<int>q;
memset(pre,-1,sizeof(pre));
memset(visited,false,sizeof(visited));
visited[start]=true;
q.push(start);
pre[start]=start;
while(!q.empty())
{
int p=q.front();
q.pop();
for(int i=0;i<n;i++)
{
if(map[p][i]>0&&!visited[i])
{
q.push(i);
visited[i]=true;
pre[i]=p;
if(i==end) return true;
}
}
}
return false;
}
int max_flow(int start,int end)
{
int i,d,flow=0;
while(bfs(start,end))
{
int d=inf;
for(i=end;i!=start;i=pre[i])
{
d=d<map[pre[i]][i]?d:map[pre[i]][i];
}
for(i=end;i!=start;i=pre[i])
{
map[pre[i]][i]-=d;
map[i][pre[i]]+=d;
}
flow+=d;
//cout<<d<<endl;
}
return flow;
}
int main()
{
int np,nc,m,u,v,z,start,end;
while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF){
memset(map,0,sizeof(map));
start=n;end=n+1;
for(int i=0;i<m;i++){
scanf(" (%d,%d)%d",&u,&v,&z);
map[u][v]=z;
}
for(int i=0;i<np;i++){
scanf(" (%d)%d",&v,&z);
map[start][v]=z;
}
for(int i=0;i<nc;i++){
scanf(" (%d)%d",&u,&z);
map[u][end]=z;
}
n+=2;
printf("%d\n",max_flow(start,end));
}
return 0;
}