[USACO 4.2.1] Drainage Ditches

题目在这里: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;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值