计蒜客——排涝(基础最大流入门)

  • 1000ms
  • 65536K

到了雨季农业生产的排涝就成了一个大问题。为了保证植物生长的顺利,某县政府决定投资为农田区建立一些排涝渠,将农田里多余的水排到小溪里。

输入第1行包括用一个空格分隔的两个整数N和M,N表示县政府专家设计的排涝渠的数量,M是排涝渠交叉点的数量。其中第一个交点是农田区,交点M是小溪(0≤N≤200,2≤M≤200)。第2行-第N+1行中每行有三个用空格分隔的整数,Si、Ei和Ci。Si和Ei说明了排涝渠的端点,多余的水自Si流向Ei;Ci是这个第i条排涝渠的最大排水量。(1≤Si,Ei≤M,0≤Ci≤10000000)

输出只有一个,为规划好的排涝渠的最大流量。

样例输入

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

样例输出

50
题解:

基础最大流入门题,这里我用的是Dinic算法。

代码:

#include <algorithm>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>

using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 205;

struct Edge
{
	int to,value,rev;//rev用于存储反向边在E[to]中的下标。
	Edge() {}
	Edge(int a,int b,int c):to(a),value(b),rev(c) {}
};

vector<Edge> E[MAXN];
int deep[MAXN];
int iter[MAXN];//当前边优化 

inline void Add(int from,int to,int value)//邻接表加入边 
{
	E[from].push_back(Edge(to,value,E[to].size()));
	E[to].push_back(Edge(from,0,E[from].size()-1));
}

bool BFS(int root,int target)//广搜分层 
{
	memset(deep,-1,sizeof deep);
	queue<int> Q;
	deep[root] = 0;
	Q.push(root);
	while(!Q.empty())
	{
		int t = Q.front();
		Q.pop();
		for(int i=0 ; i<E[t].size() ; i++)
		{
			if(E[t][i].value > 0 && deep[E[t][i].to] == -1)
			{
				deep[E[t][i].to] = deep[t] + 1;
				Q.push(E[t][i].to);
			}
		}
	}
	return deep[target] != -1;
}

int DFS(int root,int target,int flow)//深搜寻找增广路径 
{
	if(root == target)return flow;
	for(int &i=iter[root] ; i<E[root].size() ; i++)
	{
		if(E[root][i].value>0 && deep[E[root][i].to] == deep[root]+1)
		{
			int nowflow = DFS(E[root][i].to,target,min(flow,E[root][i].value));
			if(nowflow > 0)
			{
				E[root][i].value -= nowflow;
				E[E[root][i].to][E[root][i].rev].value += nowflow;
				return nowflow;
			}
		}
	}
	return 0;
}

int Dinic(int root,int target)
{
	int sumflow = 0;
	while(BFS(root,target))
	{
		memset(iter,0,sizeof iter);
		int mid;
		while((mid=DFS(root,target,INF)) > 0)
		{
			sumflow += mid;
		}
	}
	return sumflow;
}

int main()
{

	int N,M;
	int s,e,c;
	while(scanf("%d %d",&N,&M)!=EOF)
	{
		for(int i=0 ; i<N ; i++)
		{
			scanf("%d %d %d",&s,&e,&c);
			Add(s,e,c);
		}
		printf("%d\n",Dinic(1,M));
	}


	return 0;
}

posted @ 2018-06-11 22:40  Assassin_poi君  阅读(195)  评论(0编辑  收藏  举报