码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3041 Asteroids

时间:2015-10-02 22:32:10      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:

题意:给出一张n*n的图,里面有k个危险的点(不会翻译),每次攻击可以破坏一行或者一列里面的点,问最少攻击几次能把这些点都破坏了。

 

解法:一开始写了个贪心……果断wa了……后来查说是匈牙利,首先建图,行和列为点,危险的点为边,构成一个二分图,答案即为最小覆盖点,而二分图的最小覆盖点就是最大匹配,最小覆盖点(我理解)的含义是最少选几个点能使所有的边都和这些点相连,而最大匹配是最多能选出几条边,使任何一个点连的边都不超过1条,至于为啥他俩的值相等就没研究了……然后学了学原理在红书上找了份代码……

 

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
int n, k;
vector <int> g[1050];
int from[1050], tot;
bool use[1050];
bool match(int x)
{
    for(int i = 0; i < g[x].size(); i++)
        if(!use[g[x][i]])
        {
            use[g[x][i]] = true;
            if(from[g[x][i]] == -1 || match(from[g[x][i]]))
            {
                from[g[x][i]] = x;
                return true;
            }
        }
    return false;
}
int hungary()
{
    tot = 0;
    memset(from, 255, sizeof from);
    for(int i = 1; i <= n; i++)
    {
        memset(use, 0, sizeof use);
        if(match(i))
            tot++;
    }
    return tot;
}
int main()
{
    while(~scanf("%d%d", &n, &k))
    {
        for(int i = 0; i < k; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            y += n;
            g[x].push_back(y);
            g[y].push_back(x);
        }
        printf("%d\n", hungary());
    }
    return 0;
}

  

POJ 3041 Asteroids

标签:

原文地址:http://www.cnblogs.com/Apro/p/4852797.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!