Sentry Robots UVA

来源:互联网 发布:淘宝商品摄影教程 编辑:程序博客网 时间:2024/05/16 14:11

该题主要用的思想在于图的最小点集覆盖等于边的最大匹配数。按照行以及列进行重新计数,然后按照匈牙利算法求出结果即可,具体实现见如下代码:

#include<iostream>#include<vector>#include<string>#include<set>#include<stack>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<iomanip>#include<cstring>#include<sstream>#include<cstdio>#include<deque>#include<functional>using namespace std;int match[2510];int area2[2510][2510];bool visit[2510];class Solve{public:int X, Y, P, W;//习惯性假设X*Y,下标还是从1开始的int area[110][110];//0 空地 1 兴趣 2 障碍pair<int, int> M[110][110];int total_r, total_c;void Init(){total_r = 0;total_c = 0;memset(area2, 0, sizeof(area2));memset(area, 0, sizeof(area));cin >> X >> Y >> P;for (int i = 0; i < P; i++){//兴趣int a, b;cin >> a >> b;area[a][b] = 1;}cin >> W;for (int i = 0; i < W; i++){//障碍int a, b;cin >> a >> b;area[a][b] = 2;}for (int i = 1; i <= X; i++){bool flag = true;for (int j = 1; j <= Y; j++){if (area[i][j] == 1){if (flag){total_r++; flag = false;}M[i][j].first = total_r;}if (area[i][j] == 2) flag = true; }}for (int j = 1; j <= Y; j++){bool flag = true;for (int i = 1; i <= X; i++){if (area[i][j] == 1){if (flag){total_c++; flag = false;}M[i][j].second = total_c;}if (area[i][j] == 2) flag = true;}}}bool dfs(int i){for (int j = 1; j <= Y; j++){if (area2[i][j] && !visit[j]){visit[j] = true;if (match[j] == -1 || dfs(match[j])){match[j] = i;return true;}}}return false;}void Deal(){Init();int ans = 0;for (int i = 1; i <= X; i++){for (int j = 1; j <= Y; j++){if (area[i][j] == 1){area2[M[i][j].first][M[i][j].second] = 1;}}}memset(match, -1, sizeof(match));X = total_r, Y = total_c;for (int i = 1; i <= X; i++){memset(visit, 0, sizeof(visit));if (dfs(i)) ans++;}cout << ans << endl;}};int main(){int C;cin >> C;Solve a;while (C--){a.Deal();}return 0;}

原创粉丝点击