#70-【Dinic】草地排水

版权声明:反正也没有人会转,下一个 https://blog.csdn.net/drtlstf/article/details/82155387

Description

每次农夫John的地里下了雨,在Bessie最喜欢的三叶草地里就要形成池塘,这会让三叶草在一段时间内被水所覆盖,要过很长时间才能重新生长。因此,农夫John要建立一套排水的沟渠使得Bessie的三叶草地一直不会被水覆盖,把水排到最近的溪流中。作为一个称职的工程师,农夫John在每条排水沟渠的开始端安装了调节器,因此他可以控制进入沟渠的水流速率。

农夫John不仅知道每条沟渠每分钟可以传输多少加仑的水,而且知道沟渠的精确布局, 将水从池塘中排出,通过复杂的网络注入到每条沟渠和溪流中。

给出所有的有关信息,确定可以从池塘中流出并流入溪流中的水的最大速率。对每个沟渠,水流的方向是唯一的,但水可以循环流动。

输入

输入包含若干测试用例。对于每个测试用例,第一行给出用空格分开的两个整数N(0 <= N <= 200)和M(2 <= M <= 200),N是农夫John挖的沟渠数量,M是这些沟渠的交叉点的数量。交叉点1是池塘,交叉点M是溪流。后面的N行每行给出3个整数:SiEiCi, SiEi (1 <= SiEi<= M)表示沟渠的两个交叉点,水从SiEi流; Ci(0 <=Ci<=10,000,000)是这条通过沟渠水流的最大流量。

输出

对每个测试用例,输出一个整数,从池塘中排水的最大流量。

样例输入

样例输出

5 4

1 2 40

1 4 20

2 4 20

2 3 30

3 4 10

50

 

模板题......

#include <iostream>
#include <queue>
#include <cstring>

#define SIZE 210
#define INF 2e+09

using namespace std;

struct edge
{
	int to, cap, reverse;
};

vector<edge> graph[SIZE];
int depth[SIZE], sink;

bool bfs(int start) // 分层
{
	int i, u, v;
	queue<int> q;
	
	memset(depth, -1, sizeof (depth));
	depth[start] = 0;
	q.push(start);
	while (!q.empty())
	{
		u = q.front();
		q.pop();
		if (u == sink)
		{
			return true;
		}
		for (i = 0; i < graph[u].size(); ++i)
		{
			v = graph[u][i].to;
			if ((depth[v] == -1) && (graph[u][i].cap > 0))
			{
				depth[v] = depth[u] + 1;
				q.push(v);
			}
		}
	}
	
	return false;
}

int dfs(int u, int flow)
{
	int i, v, ret = 0, delta;
	
	if (u == sink)
	{
		return flow;
	}
	for (i = 0; i < graph[u].size(); ++i)
	{
		edge &temp = graph[u][i];
		v = temp.to;
		if ((temp.cap > 0) && (depth[v] == depth[u] + 1))
		{
			delta = dfs(v, min(flow - ret, temp.cap));
			if (delta > 0)
			{
				ret += delta;
				temp.cap -= delta;
				graph[v][temp.reverse].cap += delta;
			}
			if (ret == flow)
			{
				return ret;
			}
		}
	}
	
	return ret;
}

int dinic(int start) // Dinic模板
{
	int maxflow = 0, delta;
	
	while (bfs(start))
	{
		delta = dfs(start, INF);
		if (!delta)
		{
			break;
		}
		maxflow += delta;
	}
	
	return maxflow;
}

int main(int argc, char** argv)
{
	int n, m, u, v, cap, i;
	
	while (~scanf("%d%d", &m, &n))
	{
		sink = n;
		for (i = 1; i <= n; ++i) // 初始化
		{
			graph[i].clear();
		}
		while (m--)
		{
			scanf("%d%d%d", &u, &v, &cap);
			graph[u].push_back({v, cap, graph[v].size()});
			graph[v].push_back({u, 0, graph[u].size() - 1});
		}
		printf("%d\n", dinic(1));
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/drtlstf/article/details/82155387
70