标签:
#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; }
标签:
原文地址:http://blog.csdn.net/cxy7tv/article/details/51367230