码迷,mamicode.com
首页 > 其他好文 > 详细

UVA_563_Crimewave

时间:2016-05-12 17:26:26      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<list>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#include<numeric>
#include<cmath>
#pragma warning(disable:4996)
using std::cin;
using std::cout;
using std::endl;
using std::stringstream;
using std::string;
using std::vector;
using std::list;
using std::pair;
using std::set;
using std::multiset;
using std::map;
using std::multimap;
using std::stack;
using std::queue;
using std::priority_queue;
const int infinity = 1000000000;
template<typename ElemType>
class Point
{
public:
	ElemType x, y;
	Point()
	{
		x = y = 0;
	}
	Point(const ElemType &X, const ElemType &Y)
	{
		x = X, y = Y;
	}
	/*
	friend Point<ElemType>operator+(const Point &point)
	{
		return{ x + point.x,y + point.y };
	}
	friend Point<ElemType>operator-(const Point &point)
	{
		return{ x - point.x,y - point.y };
	}*/
	void operator+=(const Point &point)
	{
		x += point.x, y += point.y;
	}
	void operator-=(const Point &point)
	{
		x -= point.x, y -= point.y;
	}
};
class Edge
{
public:
	int from, to, flow, capacity;
	Edge(const int &v, const int &a, const int &c, const int &f)
	{
		from = v, to = a, capacity = c, flow = f;
	}
};
class Network
{
private:
	int vexnum, edgenum;//表示顶点个数和边个数
	int source, destination;//表示源点和汇点
	int bank;
	int max_flow;//最大流
	vector<Edge>edge;//边数的两倍
	vector<vector<int>>adjList;//邻接表
public:
	void addEdge(const int &from, const int &to, const int &capacity)
	{
		edge.push_back({ from,to,capacity,0 });
		adjList[from].push_back(edge.size() - 1);
		edge.push_back({ to,from,0,0 });
		adjList[from].push_back(edge.size() - 1);
		//cout << from << ' ' << to << endl;
		//cout << to << ' ' << from << endl;
	}
	Network()
	{
		max_flow = 0;
		vector<Point<int>>increment;
		increment.push_back({ -1,0 });
		increment.push_back({ 1,0 });
		increment.push_back({ 0,-1 });
		increment.push_back({ 0,1 });
		int row, column;
		cin >> row >> column >> bank;
		vexnum = 2 * row*column + 2;//点+源点+汇点
		source = 0, destination = vexnum - 1;
		adjList.resize(vexnum);
		//拆点
		for (int i = 1; i <= row; i++)
		{
			for (int j = 1; j <= column; j++)
			{
				auto first = (i - 1)*column + j;//前点()
				auto second = first + row*column;//后点
				addEdge(first, second, 1);//建立前点和后点的关系
				for (int k = 0; k < 4; k++)
				{
					//如果该点不在边上
					auto x = i + increment[k].x;auto y = j + increment[k].y;
					if (x >= 1 && x <= row&&y >= 1 && y <= column)
					{
						//具体化这个相邻点
						//找到该点的前点
						auto First = (x - 1)*column + y;
						//连接当前点的后点和相邻点的前点
						addEdge(second, First, 1);
					}
					else
					{
						addEdge(second, destination, 1);
					}
				}
			}
		}
		//读入银行位置
		for (int i = 0; i < bank; i++)
		{
			int x, y; cin >> x >> y;
			auto first = (x - 1)*column + y;//前点
			addEdge(source, first, 1);
		}
	}
	void getMaxFlow()
	{
		vector<int>path(vexnum);
		while (1)
		{
			vector<int>augument(vexnum);
			queue<int>Q;
			Q.push(source);
			augument[source] = infinity;
			while (!Q.empty())
			{
				auto x = Q.front();
				Q.pop();
				for (int i = 0; i < adjList[x].size(); i++)
				{
					auto e = edge[adjList[x][i]];
					if (!augument[e.to] && e.capacity>e.flow)
					{
						path[e.to] = adjList[x][i];
						augument[e.to] = std::min(augument[x], e.capacity - e.flow);
						Q.push(e.to);
					}
				}
				if (augument[destination])
				{
					break;
				}
			}
			if (!augument[destination])
			{
				break;
			}
			for (auto u = destination; u != source; u = edge[path[u]].from)
			{
				edge[path[u]].flow += augument[destination];
				edge[path[u] ^ 1].flow -= augument[destination];
			}
			max_flow += augument[destination];
		}
	}
	void print()
	{
		if (max_flow == bank)
		{
			cout << "possible" << endl;
		}
		else
		{
			cout << "not possible" << endl;
		}
	}
};
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int n; cin >> n;
	while (n--)
	{
		Network network;
		network.getMaxFlow();
		network.print();
	}
	return 0;
}

UVA_563_Crimewave

标签:

原文地址:http://blog.csdn.net/cxy7tv/article/details/51367230

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!