网络最大流(SAP)

#include <iostream>
#include <cstring>
using namespace std;
#define maxn 40010
#define maxm 99999
#define Type int
struct Graph {
	int gap[maxn], pre[maxn], cur[maxn], dis[maxn];
	int NE, NV;
	int head[maxn];
	int from[maxn];
//	int flow_in_point[maxn];
	struct Node{
		int pos,next;
		Type c;
	}E[maxm];
	template<class T> inline void checkmin(T &a,const T &b)	{if(a < 0 || a > b)a = b;}
	Type sap(int s,int t) {
		memset(dis,0,sizeof(dis[0])*NV);
		memset(gap,0,sizeof(gap[0])*NV);
	//	memset(flow_in_point, 0, sizeof(flow_in_point));
		for(int i = 0 ; i < NV ; i ++) cur[i] = head[i];
		int u = pre[s] = s;
		Type maxflow = 0,aug = -1;
		gap[0] = NV;
		while(dis[s] < NV) {
loop:		for(int &i = cur[u]; i != -1; i = E[i].next) {
				int v = E[i].pos;
				if(E[i].c && dis[u] == dis[v] + 1) {
					checkmin(aug , E[i].c);
					pre[v] = u;
					u = v;
					if(v == t) {
						maxflow += aug;
						for(u = pre[u];v != s;v = u,u = pre[u]) {
						//	if(pre[v] == from[v])
						//		flow_in_point[v] += aug;
						//	else
						//		flow_in_point[v] -= aug;
							E[cur[u]].c -= aug;
							E[cur[u]^1].c += aug;
						}
						aug = -1;
					}
					goto loop;
				}
				
			}
			int mindis = NV;
			for(int i = head[u]; i != -1 ; i = E[i].next) {
				int v = E[i].pos;
				if(E[i].c && mindis > dis[v]) {
					cur[u] = i;
					mindis = dis[v];
				}
			}
			if( (--gap[dis[u]]) == 0)    break;
			gap[ dis[u] = mindis+1 ] ++;
			u = pre[u];
		}
		return maxflow;
	}
	void Insert(int u,int v,Type c,Type cc = 0) {
		E[NE].c = c;	E[NE].pos = v;
		E[NE].next = head[u];	head[u] = NE++;

		E[NE].c = cc;	E[NE].pos = u;
		E[NE].next = head[v];	head[v] = NE++;
	}

	void init(int n) {
		NV = n;
		for(int i = 0 ; i < NV ; i ++) head[i] = -1;
		NE = 0;	
	}
}G;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值