详细的最大流基础:http://course.cug.edu.cn/cugFirst/operational_research/main/charpter7/p4.htm#
http://www.cppblog.com/mythit/archive/2009/04/19/80470.aspx(里边有点小错误,很明显,但解释的通俗易懂)
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <queue>
#include <limits.h>
#define MAX 250
using namespace std;
int cap[MAX][MAX];
int m;
int EKarp(int s,int t)
{
queue<int> Q;
int flow[MAX][MAX],a[MAX],u,v,f,pre[MAX];
f = 0;
memset(flow,0,sizeof(flow));
while(1)
{
Q.push(s);
memset(a,0,sizeof(a));
a[s] = INT_MAX; ///a[i]存储的是源点s到节点i的路径上的最小残留量,因为a[i]总是整数.于是可用它来替代标记数组
while( !Q.empty() )
{
u = Q.front();
Q.pop();
for(v=1; v<=m; v++)
if( !a[v] && cap[u][v] > flow[u][v] )
{
Q.push(v);
a[v] = a[u] < cap[u][v] - flow[u][v] ? a[u] : cap[u][v] - flow[u][v]; //增广路径最小的残留容量
pre[v] = u;
}
}
if( a[t] == 0 ) //没有了增广路径,就停止了
break;
for(u=t; u!=s; u=pre[u])
{
flow[pre[u]][u] += a[t]; //正向流增加
flow[u][pre[u]] -= a[t]; //反向流减少
}
f += a[t];
}
return f;
}
int main()
{
int from,to,c,n,ans;
while( scanf("%d%d",&n,&m) != EOF )
{
memset(cap,0,sizeof(cap));
while( n-- )
{
scanf("%d%d%d",&from,&to,&c);
cap[from][to] += c; //注意,不一定只有一条边,每两点间
}
ans = EKarp(1,m);
printf("%d\n",ans);
}
system("pause");
return 0;
}
poj 1273 最大流 基础题 (内有最详细的最大流分析,很好入门)
最新推荐文章于 2023-10-18 14:54:06 发布