最大流的第一道题,刚开始学这玩意儿,感觉好难啊!哎·····
希望慢慢地能够理解一点吧!
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define inf 1000000
#define min(a,b) a<b?a:b
int map[210][210],pre[210],maxf[210];
int n,m;
int bfs()//搜索,截止找不到增广路
{
int i;
queue<int>q;
for(i=0;i<=m;i++)
{
maxf[i]=inf;
pre[i]=-1;
}
pre[1]=0;
q.push(1);
while(!q.empty())
{
int qian=q.front();
q.pop();
int hou;
for(hou=1;hou<=m;hou++)
{
if(map[qian][hou]&&pre[hou]==-1)
{
pre[hou]=qian;
maxf[hou]=min(maxf[qian],map[qian][hou]);
q.push(hou);
}
}
}
if(pre[m]==-1)return 0;
return maxf[m];
}
int ek()//更新与修复
{
int max=0,kejia;
while(kejia=bfs())
{
max+=kejia;
int index=m,qian;
while(index!=1)
{
qian=pre[index];
map[qian][index]-=kejia;
map[index][qian]+=kejia;
index=qian;
}
}
return max;
}
int main()
{
int i,u,v,w,ans;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
map[u][v]+=w;
}
ans=ek();
printf("%d\n",ans);
}
return 0;
}
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532
网络流 定义:流网络G(V,E)是一个V有向图,其中S为源点,T为汇点。 定义:C(u,v)为u到v的容量
,其中对于每条边(u,v)∈E,有C(u,v)≥0。否则C(u,v)=0。
定义:(u,v)为u到v的流量,对所有u,v∈V, 有f(u,v)≤c(u,v)。∑f(u,v)称作网络的流
记作
f(S,T) 定义:max(∑f(u,v))=max(f(S,T))为网络的最大流量。记住|f(s,t)|
残留网络
定义:Cf(u,v)为u到v的残留容量, Cf(u,v)=C(u,v)-f(u,v)。
定义:残留网络Ef={(u,v)∈VXV,Cf(u,v)}石油残留边组成的网络。
定义:增广路径是起点为S,终点为T的一组边集,其中Cf(p)=min{cf(u,v):(u,v)∈p}称为增广路径的容量。
最大流最小割定义:割(S,T)将网络分成两部分,割得流等于∑c(u,v) ,(u∈S,v∈T) 记作c(S,T)。
明显f(S,T)≤c(S,T),我们以后用c(S,T) 表达最小割。
定理:若残留网络中不存在增广路,则当前流为最大流
定理:最大流等于最小割
证明:
假设残留图
Gf
不存在增广路径,根据以下规则划分两个点集合S={v∈V:Gf 存在从s到v的路径}
T={v∈V:v∉S}
因为Gf不存在增广路,所以t ∉S, 对顶点u,v, 若u∈S,f(u,v)=c(u,v),则v属于T,否则v属于S,
此时f(S,T)=C(S,T),
f(S,T)<=C(S,T) 所以f(S,T)为最大流,此时残留图中无增广路