题目在这里:http://wikioi.com/problem/1993/
关于sap,终于找到了一个可行的模版,而且速度还可以,关键就是怕递归爆栈(可能性很小吧)
变量名有点长,那是方便理解,另外网络的储存用的是边式储存(因为我发现了邻接矩阵的BUG)
好了,网络流就是那样的东西,有些地方还真的就不好说清楚,自己慢慢悟吧……
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define clean(x,y) memset((x),(y),sizeof(x))
#define loop(i,Point) for(i=head[Point];i!=-1;i=a[i].next)
#define MaxN 410
using namespace std;
const int INF=~0u>>1;
struct EdgeNode
{
struct edge
{
int v,cap,next;
edge():next(-1){}
}a[MaxN];
int head[MaxN],p[MaxN];
int h[MaxN],v[MaxN],n,m,tot;
inline void AddEdge(int vs,int vt,int w)
{
a[++tot].cap=w;
a[tot].v=vt;
if(head[vs]==-1)
head[vs]=tot;
else
a[p[vs]].next=tot;
p[vs]=tot;
}
int sap(int p,int AddFlow)
{
if(p==n) return AddFlow;
int OutSum=0,DFS_Flow,i;
loop(i,p)
{
if(h[a[i].v]+1==h[p]&&a[i].cap>0)
{
DFS_Flow=sap(a[i].v,min(a[i].cap,AddFlow-OutSum));
a[i].cap-=DFS_Flow;
a[i^1].cap+=DFS_Flow;
OutSum+=DFS_Flow;
if(OutSum==AddFlow) return OutSum;
}
}
if(OutSum==0&&h[1]<n)
{
if(!--v[h[p]++]) h[1]=n;
v[h[p]]++;
}
return OutSum;
}
inline void init()
{
int x,y,w;
cin>>m>>n;
clean(head,-1);
clean(h,0);
clean(v,0),v[0]=n;
tot=-1;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&w);
AddEdge(x,y,w);
AddEdge(y,x,0);
}
}
inline int MaxFlow()
{
int ans=0;
while(h[1]<n)
ans+=sap(1,INF);
return ans;
}
}NF;
int main()
{
//freopen("in","r",stdin);
//freopen("out","w",stdout);
NF.init();
cout<<NF.MaxFlow();
return 0;
}