题意:有一个r*c的网格,每列有两个白色块其他都是黑色块,一个人射箭要求在每列都射中一个白块,且所有白块都不在同一行,问是否可以做到,并输出每列射中了第几行的白块。
题解:二分图匹配,把每行的白块所在列都存起来,因为行上的白块不能共存,所以同一行白块在不同集合中。
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
const int N = 1005;
int r, c, link[N], vis[N], s[N];
vector<int> g[N];
bool dfs(int u) {
for (int i = 0; i < g[u].size(); i++) {
if (!vis[g[u][i]]) {
vis[g[u][i]] = 1;
if (link[g[u][i]] == -1 || dfs(link[g[u][i]])) {
link[g[u][i]] = u;
return true;
}
}
}
return false;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &r, &c);
memset(link, -1, sizeof(link));
for (int i = 0; i <= r; i++)
g[i].clear();
int a;
for (int i = 1; i <= c; i++)
for (int j = 0; j < 2; j++) {
scanf("%d", &a);
s[i] = a;
g[a].push_back(i);
}
int res = 0;
for (int i = 1; i <= r; i++) {
memset(vis, 0, sizeof(vis));
if (dfs(i))
res++;
}
if (res != r)
printf("NO\n");
else {
for (int i = 1; i <= c; i++) {
if (i != 1)
printf(" ");
if (link[i] != -1)
printf("%d", link[i]);
else
printf("%d", s[i]);
}
printf("\n");
}
}
return 0;
}