/* 返回顶部 */

POJ3041 Asteroids

gate

用时:看了题解之后20min左右吧...

给一个\(N\times N\)的网格,有\(k\)个障碍物,每次可以消灭一行或一列的障碍物,问至少几次可以清空。
把横、纵分为两个点集,每个障碍物\((i,j)\)即在\(i,j\)连一条边。
\(Konig定理\):最小覆盖数 = 最大匹配数
求二分图匹配即可。

code

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;

const int maxn = 505;
int n,k,x,y,ans,cp[maxn];
bool vis[maxn],to[maxn][maxn];

bool find(int x){
    for(int i = 1;i <= n;i++)
        if(to[x][i] && !vis[i]){
            vis[i] = true;
            if(!cp[i] || find(cp[i])){
                cp[i] = x;
                return true;
            }
        }
    return false;
}

int main(){
    scanf("%d%d",&n,&k);
    for(int i = 1;i <= k;i++){
        scanf("%d%d",&x,&y);
        to[x][y] = true;
    }
    for(int i = 1;i <= n;i++){
        memset(vis,0,sizeof(vis));
        if(find(i)) ans++;
    }
    printf("%d\n",ans);
    return 0;
}
posted @ 2020-07-07 15:59  Mogeko  阅读(92)  评论(0编辑  收藏  举报