UVA_563_Crimewave

来源:互联网 发布:山东临沂知历代书法家 编辑:程序博客网 时间:2024/06/03 23:43
#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;}
<pre name="code" class="cpp">#include<iostream>  #include<sstream>  #include<string>  #include<vector>  #include<list>  #include<set>  #include<map>#include<stack>  #include<queue>  #include<algorithm>  #include<numeric>  #include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#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 MaxVexNum = 5002;const int INF = 1000000000;class Edge{public:int to, capacity, flow;Edge(int t, int c, int f){to = t,capacity = c,flow = f;}};vector<pair<int, int>>direction{ {0,-1},{0,1},{1,0},{-1,0} };class Network{private:int vexnum, edgenum, source, destination,maxflow;vector<vector<Edge>>adjList;public:void addEdge(int from, int to, int cap){adjList[from].push_back({ to, cap, (int)adjList[to].size() });adjList[to].push_back({ from, 0, (int)adjList[from].size() - 1 });}Network(){adjList.resize(MaxVexNum);int row, column; cin >> row >> column >> vexnum;source = 0, destination = 2 * row*column + 1;//链接source到银行处for (int i = 0; i < vexnum; i++){int x, y; cin >> x >> y;auto first = (x - 1)*column + y, second = first + row*column;addEdge(source, first, 1);}//拆点,连每个点的前后点for (int i = 1; i <= row; i++){for (int j = 1; j <= column; j++){auto first = (i - 1)*column + j, second = first + row*column;addEdge(first, second, 1);for (int k = 0; k < 4; k++){int x = i + direction[k].first, y = j + direction[k].second;auto FIRST = (x - 1)*column + y, SECOND = FIRST + row*column;if (x >= 1 && x <= row&&y>=1 && y <= column){addEdge(second, FIRST,1);}}if (i == 1 || i == row || j == 1 || j == column){addEdge(second,destination,1);}}}}int dfs(int src, int sink, int flow,vector<bool>&used){if (src == sink){return flow;}used[src] = true;for (int i = 0; i<adjList[src].size(); i++){Edge &edge = adjList[src][i];if (!used[edge.to] && edge.capacity>0){int minflow = dfs(edge.to, sink, std::min(flow, edge.capacity),used);if (minflow>0){edge.capacity -= minflow;adjList[edge.to][edge.flow].capacity += minflow;return minflow;}}}return 0;}void getMaxFlow(){maxflow = 0;while (1){vector<bool>used(MaxVexNum);int f = dfs(source, destination, INF,used);if (!f){return;}maxflow += f;}}void print(){if (vexnum == maxflow){cout << "possible" << endl;}else{cout << "not possible" << endl;}}};int main(){//freopen("input.txt", "r", stdin);//freopen("output.txt", "w", stdout);int T; cin >> T;while (T--){Network network;network.getMaxFlow();network.print();}return 0;}



0 0
原创粉丝点击