对于这种x,y坐标的,算是老套路了,每个点就是把x,y连在一起
选取最少点覆盖所有的x,y,那么就是个二分图匹配,只是这题有障碍物,所以需要拆点,重新赋值行和列
思路代码参考这篇文章
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <map>
#define LL long long
#define ULL unsigned long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define pi acos(-1)
#define fuck() (cout << "--------" << endl)
const int maxn = 100 + 5;
using namespace std;
int maps[maxn][maxn];//障碍1 重要2
int mapss[maxn][maxn];
int link[maxn];
bool vis[maxn];
pair<int,int> g[maxn][maxn];
int row,col;
void init(){
row = col = 0;
memset(vis, false, sizeof(vis));
memset(link, -1, sizeof(link));
memset(maps, 0, sizeof(maps));
memset(mapss, 0, sizeof(mapss));
}
bool dfs(int x){
for(int i=1; i<=col; i++){
if(!vis[i] && mapss[x][i]){
vis[i] = true;
if(link[i] == -1 || dfs(link[i])){
link[i] = x;
return true;
}
}
}
return false;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
init();
int x,y;
int posx,posy;
scanf("%d%d",&x,&y);
int blo,imp;
scanf("%d",&blo);
for(int i=0; i<blo; i++){
scanf("%d%d",&posx,&posy);
maps[posx][posy] = 1;
}
scanf("%d",&imp);
for(int i=0; i<imp; i++){
scanf("%d%d",&posx,&posy);
maps[posx][posy] = 2;
}
for(int i=1; i<=x; i++){
bool flag = true;
for(int j=1; j<=y; j++){
if(maps[i][j] == 1){
if(flag) row++;
g[i][j].first = row;
flag = false;
}
if(maps[i][j] == 2) flag = true;
}
}
for(int j=1; j<=y; j++){
bool flag = true;
for(int i=1; i<=x; i++){
if(maps[i][j] == 1){
if(flag) col++;
g[i][j].second = col;
flag = false;
}
if(maps[i][j] == 2) flag = true;
}
}
for(int i=1; i<=x; i++)
for(int j=1; j<=y; j++)
if(maps[i][j] == 1)
mapss[g[i][j].first][g[i][j].second] = 1;
int ans = 0;
for(int i=1; i<=row; i++){
memset(vis, false, sizeof(vis));
if(dfs(i)) ans++;
}
printf("%d\n",ans);
}
}