【题意】n个节点,其中np个发电厂,nc个用户,其他是过路点。有m条边,从a到b最大运输w单位的电。发电厂有最大出电量,用户有最大入电量。问用户最终能得到多少电。
【思路】超级源点指向所有的发电站,容量是发电站的发电量,所有的用户指向超级汇点,容量是用电量,其他边按题意建。
【重点】【EK算法】建图之后就是跑FF...结果T了...果然DFS是要比BFS慢的...用EK过。
【路径的存储】DFS是递归的,它的path可以一个个点存储,但是BFS事先不知道能否到达终点,所以path[a]要存a的前面的节点。
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int M=2505;
const int inf=99999999;
int mp[M][M];
int n,m,np,nc;
int start,end;
int pathf[M];
int temp,ans;
std::queue<int>q;
void bfs(int x)
{
while(!q.empty())
q.pop();
pathf[x]=0;
q.push(x);
while(!q.empty())
{
int t=q.front();
if(t==end)
return;
for(int i=0; i<=end; i++)//
{
if(mp[t][i]>0&&pathf[i]==-1)
{
pathf[i]=t;//现在path不是一个个存了,path[a]里存的是a的前一个节点。
q.push(i);
}
}
q.pop();
}
return;
}
int main()
{
while(~scanf("%d%d%d%d",&n,&np,&nc,&m))
{
ans=0;
memset(mp,0,sizeof(mp));
start=0,end=n+1;
while(m--)
{
int f,t,w;
while(getchar()!='(');
scanf("%d,%d)%d",&f,&t,&w);
f++;
t++;
mp[f][t]=w;
}
for(int i=0; i<np; i++)
{
int t,w;
while(getchar()!='(');
scanf("%d)%d",&t,&w);
t++;
mp[start][t]=w;
}
for(int i=0; i<nc; i++)
{
int t,w;
while(getchar()!='(');
scanf("%d)%d",&t,&w);
t++;
mp[t][end]=w;
}
while(1)
{
// for(int i=0; i<=n+1; i++)
// {
// for(int j=0; j<=n+1; j++)
// {
// printf("%d ",mp[i][j]);
// }
// printf("\n");
// }
// puts("");
temp=inf;
memset(pathf,-1,sizeof(pathf));
bfs(start);
int now=end;
if(pathf[end]==-1)
break;
while(now!=start)
{
int pre=pathf[now];//
temp=std::min(temp,mp[pre][now]);
now=pre;
}
now=end;
while(now!=start)
{
int pre=pathf[now];
mp[pre][now]-=temp;
mp[now][pre]+=temp;
now=pre;
}
ans+=temp;
}
printf("%d\n",ans);
}
}