3041 Asteroids(二分圖最大匹配)
阿新 • • 發佈:2018-12-24
題意
在一個的網格上,分佈著個行星。
Bessie擁有一種能力,每次可以消滅一行或一列的行星。
求Bessie最少需要多少次才可以消滅所有的行星。
輸入
輸入。
接下來行,每行輸入2個整數,表示一個行星的座標。
輸出
輸出最少的次數
思路
把每行、每列都當作一個節點,網格中的點看作這些節點的邊,即若有一個點的座標是,則認為第2行和第3列有一條邊。
問題就轉換成求最小點覆蓋問題。最少需要多少個節點就可以覆蓋所有的邊。
根據最小割定理可以知道,最小點覆蓋問題等價於最大匹配問題。
程式碼
#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
const int N = 1e3 + 10;
vector<int> g[N];
int c[N];
bool vis[N];
bool dfs(int u) {
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (vis[v])
continue;
vis[v] = true;
if (c[v] == -1 || dfs(c[v])) {
c[v] = u;
return true;
}
}
return false;
}
int main() {
int n, k, t;
scanf("%d%d", &n, &k);
for (int i = 0; i < k; i++) {
int x, y;
scanf("%d%d", &x, &y);
g[x].push_back(y + n);
g[y + n].push_back(x);
}
memset (c, -1, sizeof(c));
int res = 0;
for (int i = 1; i <= n; i++) {
memset(vis, false, sizeof(vis));
if (dfs(i))
res = res + 1;
}
printf("%d\n", res);
return 0;
}