最大流dinic算法板子

FZSZ Online Judge #334. 最大流

题目描述

这是一道网络流模板题。

你需要求出点1到点n的最大流。

本题时限2s,空间限制512M(大概相当于正常机子4s)

数据已更新

输入格式

输入第一行为两个正整数n和m。

以下m行每行三个正整数aibici,表示aibi有一条容量为ci的单向边。

输出格式

一行输出最大流。

输入样例

2 1
1 2 3

输出样例

3

数据范围

1n30001m2000001ai,bin0ci1000

#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<queue>
#define TOTAL_EDGE 400011
#define TOTAL_POINT 6011
#define INF 2147483647
#define cmin(a,b) a<b?a:b
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
struct Max_Flow{
	int n,m,tot,x,y,z,S,T;
	int nxt[TOTAL_EDGE],las[TOTAL_POINT],to[TOTAL_EDGE],c[TOTAL_EDGE],dep[TOTAL_POINT];
	std::queue<int>q;
	int read(){
		char c=getchar();
		while(c<'0'||c>'9')
			c=getchar();
		int data=0;
		while(c>='0'&&c<='9')
			data=(data<<1)+(data<<3)+c-'0',c=getchar();
		return data;
	}
	void add(int x,int y,int z){
		nxt[++tot]=las[x];
		las[x]=tot;
		to[tot]=y;
		c[tot]=z;
	}
	void adde(int x,int y,int z){
		add(x,y,z);
		add(y,x,0);
	}
	void init(){
		tot=1;
		n=read();
		m=read();
		FOR(i,1,m){
			x=read();
			y=read();
			z=read();
			adde(x,y,z);
		}
		S=1;
		T=n;
	}
	int bfs(){
		FOR(i,S,T)
			dep[i]=0;
		dep[1]=1;
		q.push(1);
		int now;
		while(!q.empty()){
			now=q.front();
			q.pop();
			for(register int e=las[now];e;e=nxt[e])
				if(c[e]>0&&!dep[to[e]]){
					dep[to[e]]=dep[now]+1;
					q.push(to[e]);
				}
		}
		return dep[T];
	}
	int dfs(int now,int flow){
		if(now==T)
			return flow;
		int ret=0,d;
		for(register int e=las[now];e&&flow;e=nxt[e])
			if(c[e]>0&&dep[to[e]]==dep[now]+1){
				d=dfs(to[e],cmin(flow,c[e]));
				c[e]-=d;
				c[e^1]+=d;
				flow-=d;
				ret+=d;
			}
		if(!ret)
			dep[now]=0;
		return ret;
	}
	void dinic(){
		int ans=0;
		while(bfs())
			ans+=dfs(S,INF);
		printf("%d\n",ans);
	}
	void work(){
		init();
		dinic();
	}
}max_flow;
int main(){
	max_flow.work();
	return 0;
}

  

posted @ 2017-10-18 16:40  Stump  阅读(304)  评论(0编辑  收藏  举报