POJ 1273 解题报告

还是按照http://blog.csdn.net/thestoryofsnow/article/details/40942009里面的刷题顺序,最简单的最大流问题。

这道题我在USACO上面已经做过了:http://blog.csdn.net/thestoryofsnow/article/details/38103513 Drainage Ditches问题

这里稍稍改动,主要是把同样两个点之间的pair的所有capacity加到一起了。用的还是我之前写的模板,dfs。
周末刷题的人好多,poj特别挤,程序一直提交不上去。周一就好多了。
Accepted436K79MSC++2427B
/* 
ID: thestor1 
LANG: C++ 
TASK: poj1273
*/
#include <iostream>  
#include <cmath>  
#include <cstdio>  
#include <cstring>  
#include <climits>  
#include <cassert>  
#include <string>  
#include <vector>  
#include <set>
#include <map>  
#include <queue>  
#include <stack>  
#include <algorithm>

using namespace std;

int find_path(vector<vector<int> > &capacity, vector<vector<int> > adjs, const int source, const int sink)
{
	int M = capacity.size();
	std::vector<bool> visited(M, false);
	// from[x] is the previous vertex visited in the shortest path from the source to x
	std::vector<int> from(M, -1);
	queue<int> Q;
	Q.push(source);
	visited[source] = true;
	int where = -1, next = -1, prev = -1;
	bool found = false;
	while (!Q.empty())
	{
		where = Q.front();
		Q.pop();
		for (int i = 0; i < adjs[where].size(); ++i)
		{
			next = adjs[where][i];
			if (!visited[next] && capacity[where][next] > 0)
			{
				Q.push(next);
				visited[next] = true;
				from[next] = where;
				if (next == sink)
				{
					found = true;
					break;
				}
			}
		}
		if (found)
		{
			break;
		}
	}

	// we compute the path capacity
	where = sink;
	int path_cap = -1;
	while (from[where] > -1)
	{
		prev = from[where];
		if (path_cap > -1)
		{
			path_cap = min(path_cap, capacity[prev][where]);
		}
		else
		{
			path_cap = capacity[prev][where];
		}
		where = prev;
	}

	// we update the residual network; if no path is found the while loop will not be entered
	where = sink;
	while (from[where] > -1)
	{
		prev = from[where];
		capacity[prev][where] -= path_cap;
		capacity[where][prev] += path_cap;
		where = prev;
	}

	// if no path is found, path_cap is infinity
	if (path_cap == -1)
	{
		return 0;
	}
	return path_cap;
}


int main()
{
	int N, M;
	while (cin >> N >> M)
	{
		vector<vector<int> > capacity(M, vector<int>(M, 0));
		vector<vector<int> > adjs(M, vector<int>());
		for (int i = 0; i < N; ++i)
		{
			int s, e, c;
			cin >> s >> e >> c;
			capacity[s - 1][e - 1] += c;
			adjs[s - 1].push_back(e - 1);
			adjs[e - 1].push_back(s - 1);
		}

		// max flow
		int maxflow = 0;

		while (true)
		{
			int path_cap = find_path(capacity, adjs, 0, M - 1);
			if (path_cap == 0)
			{
				break;
			}
			else
			{
				maxflow += path_cap;
			}
		}

		cout << maxflow << endl;
	}

	return 0;  
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值