这题是多源点多汇点的问题,对于此类问题,只要建立一个超级原点,和超级汇点就行了 ,超级源点可以到原图中所有的点,原图中所有的点都可以到超级汇点。而解决最大流问题用的是EK算法。 不了解的请自行百度。
#include<iostream>
#include<queue>
using namespace std;
#define MAXSIZE 130
int map[MAXSIZE][MAXSIZE];
int pre[MAXSIZE];
queue<int>que;
int n,np,nc,m;
int bfs(int src,int dec)//源点和汇点
{
memset(pre,-1,sizeof(pre));
while(!que.empty())que.pop();
pre[src]=src;
que.push(src);
int temp;
while(!que.empty())
{
temp=que.front();
que.pop();
if(temp==dec)
break;
for(int i=0;i<n+2;i++)
{
if(map[temp][i]&&pre[i]==-1)//如果有路径 并且 还没有用过
{
pre[i]=temp;
que.push(i);
}
}
}
if(temp==dec)
return 1;
else
return 0;
}
int maxFlow(int src,int dec)
{
int ans=0;
while(bfs(src,dec))
{
int i;
int min=999999;
for(i=dec;i!=src;i=pre[i])
{
min=min>map[pre[i]][i]?map[pre[i]][i]:min;
}
for(i=dec;i!=src;i=pre[i])
{
map[pre[i]][i]-=min;
map[i][pre[i]]+=min;
}
ans+=min;
}
return ans ;
}
int main()
{
int i;
char ss[50];
int a,b,c;
int src,dec;
while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
{
memset(map,0,sizeof(map));
src=n;
dec=n+1;
for(i=0;i<m;i++)
{
scanf("%s",ss);
sscanf(ss,"(%d,%d)%d",&a,&b,&c);
map[a][b]=c;
}
for(i=0;i<np;i++)
{
scanf("%s",ss);
sscanf(ss,"(%d)%d",&a,&b);
map[src][a]=b;
}
for(i=0;i<nc;i++)
{
scanf("%s",ss);
sscanf(ss,"(%d)%d",&a,&b);
map[a][dec]=b;
}
printf("%d\n",maxFlow(src,dec));
}
return 0;
}