题干:

现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条水渠,给出这n条水渠所连接的点和所能流过的最大流量,求从源点到汇点能流过的最大流量。

Input

输入包括几种情况。 对于每种情况,第一行包含两个空格分隔的整数,N(0 <= N <= 200)和M(2 <= M <= 200)。 N是Farmer John挖的沟渠数量。 M是那些沟渠的交叉点。 以下N行中的每一行包含三个整数,Si,Ei和Ci。 Si和Ei(1 <= Si,Ei <= M)表示该沟渠流动的交叉点。 水将从Si流到Ei。 Ci(0 <= Ci <= 10,000,000)是水流过沟渠的最大速率。

Output

最大流量

Sample Input

5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10

Sample Output

50

解题报告:

   这是一道KK,EK,dinic都可以0ms跑过的板子题。。

AC代码:

#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
int tot;
struct Edge {
	int to,ne,v;
} e[100005 * 2];
int head[10005];
int st,ed;
int dis[10050],q[10005];//一共多少个点跑bfs,dis数组和q数组就开多大。 
void insert(int u,int v,int w) {
	e[++tot].to=v;
	e[tot].v=w;
	e[tot].ne=head[u];
	head[u]=tot;
}
bool bfs(int st,int ed) {
	memset(dis,-1,sizeof(dis));
	int front=0,tail=0;
	q[tail++]=st;
	dis[st]=0;
	while(front<tail) {
		int cur = q[front];
		front++;
		for(int i = head[cur]; i!=-1; i = e[i].ne) {
			if(e[i].v&&dis[e[i].to]<0) {
				q[tail++]=e[i].to;
				dis[e[i].to]=dis[cur]+1;
			}
		}
	}
	if(dis[ed]==-1) return 0;
	return 1;
}
int dfs(int cur,int f) {
	if(cur==ed) return f;
	int w,flow=0;
	for(int i = head[cur]; i!=-1; i = e[i].ne) {		
		if(e[i].v&&dis[e[i].to]==dis[cur]+1) {
			w=f-flow;
			w=dfs(e[i].to,min(w,e[i].v));
			e[i].v-=w;
			e[i+1].v+=w;
			flow+=w;
			if(flow==f) return f;
		}		
	}
	if(!flow)dis[cur]=-1;
	return flow;
}
int dinic() {
	int ans = 0;
	while(bfs(st,ed)) ans+=dfs(st,0x7fffffff);
	return ans;
}
int main() {

	while(~scanf("%d%d",&m,&n)) {
		tot=2;
		st=1,ed=n;
		for(int i = 1; i<=n; i++) head[i] = -1;
		for(int a,b,c,i = 1; i<=m; i++) {
			scanf("%d%d%d",&a,&b,&c);
			insert(a,b,c);
			insert(b,a,0);
		}		
		printf("%d\n",dinic());				
	}

	return 0;
}