POJ 3041【最小点覆盖】

POJ 3041 Asteroids

最小点覆盖:选择一个点能够与它相连的所有边,选择一个最小的点集能够覆盖二分图中所有的边。

最小点覆盖==最大匹配

匈牙利算法求解

#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 0x3f3f3f3f
#define lowbit(x) x & (-x)
using namespace std;
typedef long long ll;
const int maxN = 505;
const int maxK = 10004;
const ll mod = 1e9+9;

int read()
{
    
    
    int x = 0, f = 1; char ch = getchar();
    while(ch < '0' || ch > '9') {
    
     if(ch == '-') f = -f; ch = getchar(); }
    while(ch >= '0' && ch <= '9') {
    
     x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

int n, k;
bool used[maxN], match[maxN][maxN];
int Left[maxN];

bool Hungary(int x) {
    
    
    for(int i = 1; i <= n; ++ i ) {
    
    
        if(match[x][i] && !used[i]) {
    
    
            used[i] = true;
            if(Left[i] == 0 || Hungary(Left[i])) {
    
    
                Left[i] = x;
                return true;
            }
        }
    }
    return false;
}

int main() {
    
    
    n = read(); k = read();
    for(int i = 0; i < k; ++ i ) {
    
    
        int x, y; x = read(); y = read();
        match[x][y] = true;
    }
    int ans = 0;
    for(int i = 1; i <= n; ++ i ) {
    
    
        memset(used, false, sizeof(used));
        if(Hungary(i)) ++ ans;
    }
    cout << ans << endl;
    return 0;
}

最小点覆盖的点是哪些?
是从一个右边未被匹配的点出发走增广路,标记增广路上的所有点。走完所有的增广路的点之后,右边未被标记的点以及左边被标记的点就是最小覆盖点集。

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/106959588