[SPOJ FASTFLOW] Fast Maximum Flow [最大流]

23 篇文章 0 订阅
8 篇文章 0 订阅

最大流模板题

isap 0.96秒 

dinic 4.5秒...


//dinic
#include <cstdio>
#include <cstring>

using namespace std;

const long long MAXINT=(1ll<<60);
const int N=5010;
const int M=30010;

struct NetWorkFlow {
	struct Node {
		int fe,h,cur;
		long long v;
	};
	struct Edge {
		int t,ne;
		long long f;
	};
	Node a[N];
	Edge b[M*2];
	int d[M];
	int s,t,n,p;
	void clear(int nn,int ss,int tt) {
		n=nn;s=ss;t=tt;
		for (int i=0;i<=n;i++) {
			a[i].fe=-1;
			a[i].v=0;
		}
		p=0;
	}
	void putedge(int x,int y,long long f) {
		b[p].t=y;
		b[p].f=f;
		b[p].ne=a[x].fe;
		a[x].fe=p;
		p++;
		b[p].t=x;
		b[p].f=f;
		b[p].ne=a[y].fe;
		a[y].fe=p;
		p++;
	}
	bool bfs() {
		int i,p,q,j;
		for (i=0;i<=n;i++) a[i].h=0;
		a[s].h=1;
		p=q=0;
		d[q++]=s;
		while (p<q) {
			i=d[p];
			for (j=a[i].fe;j!=-1;j=b[j].ne) {
				if (a[b[j].t].h==0&&b[j].f>0) {
					a[b[j].t].h=a[i].h+1;
					if (b[j].t==t) return true;
					d[q++]=b[j].t;
				}
			}
			p++;
		}
		return false;
	}
	long long dfs(int i,long long v) {
		if (i==t) {
			a[t].v+=v;
			return v;
		}
		int j;
		long long ans=0,x;
		for (j=a[i].cur;j!=-1&&v>0;j=b[j].ne) {
			if (b[j].f>0&&a[b[j].t].h>a[i].h) {
				if (b[j].f<v) x=dfs(b[j].t,b[j].f);
				else x=dfs(b[j].t,v);
				v-=x;
				b[j].f-=x;
				b[j^1].f+=x;
				ans+=x;
			}
		}
		a[i].cur=j;
		a[i].v+=ans;
		return ans;
	}
	long long flow() {
		int i;
		a[s].v=MAXINT;
		while (bfs()) {
			for (i=0;i<=n;i++) a[i].cur=a[i].fe;
			dfs(s,MAXINT);
		}
		return a[t].v;
	}
};

NetWorkFlow c;
int n,m;

int main() {
	int i,x,y,z;
	scanf("%d%d",&n,&m);
	c.clear(n,1,n);
	for (i=0;i<m;i++) {
		scanf("%d%d%d",&x,&y,&z);
		c.putedge(x,y,z);
	}
	printf("%lld\n",c.flow());
	return 0;
}

//isap
#include <cstdio>
#include <cstring>

using namespace std;

const long long MAXINT=(1ll<<60);
const int N=5010;
const int M=30010;

struct NetWorkFlow {
	struct Edge {
		int t;
		long long f;
		Edge *ne,*p;
		Edge () {}
		Edge (int tt,int ff,Edge *nee) {
			t=tt;f=ff;ne=nee;
		}
		void *operator new(size_t,void *p) {
			return p;
		}
	};
	Edge b[M*2];
	Edge *p,*fe[N],*cur[N];
	int n,s,t;
	int h[N],vh[N];
	void clear(int nn,int ss,int tt) {
		n=nn;s=ss;t=tt;
		for (int i=0;i<=n;i++) fe[i]=NULL;
		p=b;
	}
	void putedge(int x,int y,int f) {
		fe[x]=new(p++)Edge(y,f,fe[x]);
		fe[y]=new(p++)Edge(x,f,fe[y]);
		fe[x]->p=fe[y];
		fe[y]->p=fe[x];
	}
	long long aug(int i,long long f) {
		if (i==t) return f;
		long long l=f;
		for (Edge *&j=cur[i];j;j=j->ne) {
			if (j->f&&h[j->t]+1==h[i]) {
				long long tmp=aug(j->t,l<j->f?l:j->f);
				j->f-=tmp;
				j->p->f+=tmp;
				l-=tmp;
				if (h[s]==n||!l) return f-l;

			}
		}
		int minh=n-1;
		for (Edge *j=cur[i]=fe[i];j;j=j->ne) {
			if (j->f&&h[j->t]<minh) minh=h[j->t];
		}
		minh++;
		if (!--vh[h[i]]) h[s]=n;
		else ++vh[h[i]=minh];
		return f-l;
	}
	long long flow() {
		long long ans=0;
		vh[0]=n;
		for (int i=0;i<=n;i++) {
			cur[i]=fe[i];
			h[i]=vh[i]=0;
		}
		while (h[s]<n) ans+=aug(s,MAXINT);
		return ans;
	}
};

NetWorkFlow c;
int n,m;

int main() {
	int i,x,y,z;
	scanf("%d%d",&n,&m);
	c.clear(n,1,n);
	for (i=0;i<m;i++) {
		scanf("%d%d%d",&x,&y,&z);
		c.putedge(x,y,z);
	}
	printf("%lld\n",c.flow());
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值