暂时最大流问题我就先掌握这一种算法吧
基本的最大流问题:
EK算法:(基于BFS)
每一次BFS更新一条路径,虽然都会入队列,但是由于以下条件保证点不会交叉,所以只有一条到终点的路径会更新流量。
if(!res[v] && map[u][v]>flow[u][v])
注意更新flow矩阵的时候是这样的:
while (u != start)
{
flow[pre[u]][u] += res[end];
flow[u][pre[u]] -= res[end];
u = pre[u];
}
表示从flow[pre[u]][u]的这条边的流量可以增加res[end]这么多,反向的流量响应的减少,下一次在计算反向流量的时候也许不等式 mp[u][pre[u]]>flow[u][pre[u]]成立
http://www.cnblogs.com/jackge/archive/2013/04/10/3012182.html
//15MS 2064K
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int VM=220;
const int INF=0x3f3f3f3f;
int n,m,max_flow; //max_flow是最大流
int map[VM][VM],flow[VM][VM]; // map[i][j]是每条边的容量,flow[i][j]是每条边的流量
int res[VM],pre[VM]; //res[]是每个点的剩余流量,pre[]是每个点的父亲
int EK(int src,int des){
max_flow=0;
queue<int> q;
while(!q.empty())
q.pop();
memset(flow,0,sizeof(flow)); //最开始每条边的流量都是0
while(1){
memset(res,0,sizeof(res)); //残余流量得变0,一开始所有点都没流入对吧
res[src]=INF; //源点嘛,剩余流量无限是必须的...
q.push(src); //从源点开始进行BFS找增广路
int u,v;
while(!q.empty()){
u=q.front();
q.pop();
for(v=1;v<=m;v++) //遍历所有点,找可行边
if(!res[v] && map[u][v]>flow[u][v]){ //该点剩余流量为0 且 容量大于流量,也就是找到了新的结点
pre[v]=u; //找到新结点,父节点得记录一下吧
q.push(v);
res[v]=min(res[u],map[u][v]-flow[u][v]); //如果u的剩余流量能填满uv就填满,不能的话就把u这点的流量全部流向uv
}
}
if(res[des]==0) //如果当前已经是最大流,汇点没有残余流量
return max_flow;
for(u=des;u!=src;u=pre[u]){ //如果还能增广,那么回溯,从汇点往回更新每条走过的边的流量
flow[pre[u]][u]+=res[des]; //更新正向流量 (注意这里更新的是流量,而不是容量)
flow[u][pre[u]]-=res[des]; //更新反向流量
}
max_flow+=res[des];
}
}
int main(){
//freopen("input.txt","r",stdin);
while(~scanf("%d%d",&n,&m)){
memset(map,0,sizeof(map));
memset(pre,0,sizeof(pre));
int u,v,w;
while(n--){
scanf("%d%d%d",&u,&v,&w);
map[u][v]+=w; //有重边
}
printf("%d\n",EK(1,m));
}
return 0;
}
比较完整的一个做法:
http://www.cnblogs.com/gabo/archive/2012/08/05/2623531.html