POJ 3041 - Asteroids(二分图匹配)

来源:互联网 发布:执行仪表板软件 编辑:程序博客网 时间:2024/06/04 18:49

题目:

http://poj.org/problem?id=3041

题意:

n*n的矩阵,给出有敌人的位置,每根剑可以伤害一行或一列,求出将敌人全部伤害的用的最少的剑数。

思路;

行为左集,列为右集,有敌人的行列连边。要将所有敌人覆盖,即将敌人所在的行或列覆盖就可以了,则转化成顶点的最小覆盖。

一个重要的定理:顶点的最小覆盖数 = 最大匹配数。

所以题目只要求最大匹配数就可以了。

AC.

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn = 505;int uN, vN;int g[maxn][maxn],linker[maxn];bool used[maxn];bool dfs(int u){    for(int v = 0; v < vN; ++v) {        if(g[u][v] && !used[v]) {            used[v] = true;            if(linker[v] == -1 || dfs(linker[v])) {                linker[v] = u;                return true;            }        }    }    return false;}int hungary(){    int res = 0;    memset(linker, -1, sizeof(linker));    for(int u = 0; u < uN; ++u) {        memset(used, 0, sizeof(used));        if(dfs(u)) res++;    }    return res;}int main(){//freopen("in", "r", stdin);    int n, m;    while(~scanf("%d %d", &n, &m)) {        for(int i = 0; i < m; ++i) {            int u, v;            scanf("%d %d", &u, &v);            u--; v--;            g[u][v] = 1;        }        uN = n; vN = n;        printf("%d\n", hungary());    }    return 0;}


0 0
原创粉丝点击