搞了许久的最大流终于有眉头了,非常高兴~~
题意:有多个发电站,有多个用户,发电站和用户之间有多个中转站。
首先输入,总共点的个数,发电站的数目,用户数,边数。
对于每个边,输入两个点,为边的两点,然后输入此边允许的一个最大流量。
对于每个发电站,和每个用户来说,输入一个点,此点为发电站的后继点或者用户的前驱点,然后输入一个最大流量;
做法:
设立一个源点sp,一个节点fp。
sp指向所有的发电站。所有的用户指向fp。求sp到fp的最大流量。
对于edmondskarp算法,首先确定所有的点的最大流量和现有流量,然后每次加一个最小的边,直至无法继续加为止。
代码:
#include<iostream>
#include<Stdio.h>
#include<string.h>
#include<queue>
#define min(a,b) (a<b?a:b);
using namespace std;
struct list
{
int flow;
int cow;
}map[105][105];
int sp,fp;
int n,np,nc,m;
int maxflow;
int prv[105];//记录每次查找最小边的路径
int bfs(int st,int end)
{
int i,v;
int a[105];
queue<int>q;
memset(a,0,sizeof(a));
memset(prv,-1,sizeof(prv));
q.push(st);
a[st]=10000;
while(!q.empty())
{
v=q.front();
q.pop();
for(i=0;i<n;i++)
{
if(!a[i]&&(map[v][i].cow>map[v][i].flow))
{
q.push(i);
prv[i]=v;
a[i]=min(a[v],map[v][i].cow-map[v][i].flow);//寻找该路径的最小边
}
}
if(v==end)return a[end];
}
return 0;
}
void edmondskarp()
{
int i,tmp;
maxflow=0;
while(bfs(sp,fp))//如果可以加边,就继续加
{
tmp=bfs(sp,fp);
for(i=fp;i!=sp;i=prv[i])
{
map[prv[i]][i].flow+=tmp;
map[i][prv[i]].flow-=tmp;
}
maxflow+=tmp;
}
}
int main()
{
int i,x,y,z;
char ch;
while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
{
memset(map,0,sizeof(map));
for(i=0;i<m;i++)
{
cin>>ch>>x>>ch>>y>>ch>>z;
map[x][y].cow=z;
}
sp=n;
fp=n+1;
n+=2;
for(i=0;i<np;i++)
{
cin>>ch>>x>>ch>>y;
map[sp][x].cow=y;
}
for(i=0;i<nc;i++)
{
cin>>ch>>x>>ch>>y;
map[x][fp].cow=y;
}
edmondskarp();
printf("%d\n",maxflow);
}
return 0;
}