poj3041 Asteroids

博客探讨了如何运用二分图最大匹配和最小覆盖点的概念来解决POJ3041 Asteroids问题。文章指出,可以通过消除一行或一列来清除所有障碍,并将横纵坐标视为节点,用边连接。最小覆盖点即为最大匹配,意味着找到消除所有障碍所需的最少操作数。
摘要由CSDN通过智能技术生成


Asteroids
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 20174 Accepted: 10948

Description

Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conveniently located at the lattice points of the grid. 

Fortunately, Bessie has a powerful weapon that can vaporize all the asteroids in any given row or column of the grid with a single shot.This weapon is quite expensive, so she wishes to use it sparingly.Given the location of all the asteroids in the field, find the minimum number of shots Bessie needs to fire to eliminate all of the asteroids.

Input

* Line 1: Two integers N and K, separated by a single space. 
* Lines 2..K+1: Each line contains two space-separated integers R and C (1 <= R, C <= N) denoting the row and column coordinates of an asteroid, respectively.

Output

* Line 1: The integer representing the minimum number of times Bessie must shoot.

Sample Input

3 4
1 1
1 3
2 2
3 2

Sample Output

2

Hint

INPUT DETAILS: 
The following diagram represents the data, where "X" is an asteroid and "." is empty space: 
X.X 
.X. 
.X.
 

OUTPUT DETAILS: 
Bessie may fire across row 1 to destroy the asteroids at (1,1) and (1,3), and then she may fire down column 2 to destroy the asteroids at (2,2) and (3,2).
今天到了二分图最大匹配,学习了一下匈牙利算法,其实感觉算法还是很简单的,难点应该是怎么应用。

其原则大概是:有机会上,没机会创造机会也要上

这里有一个非常有趣的教程:http://blog.csdn.net/dark_scope/article/details/8880547。

然后这个题就是给你障碍的坐标,你有一个非常腻害的阿姆斯特丹回旋加速炮,一次可以直接消灭掉一整行或者一整列的障碍(好阔怕qwq)

我们把横坐标和纵坐标分开,每个坐标点之间连一条边,想想看,怎么样就可以全消灭掉,只要找到最小覆盖点就OK了对吧

借用别人的话:现在的问题是 我们要在新图中选择最少的点使得所有边都至少有一个端点被选中了.(想想是不是就等价于原问题使用武器次数最少?)

最小覆盖点就是最大匹配。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
const int MAXN=500+5;

int n,m;
int vis[MAXN],match[MAXN];
vector<int>head[MAXN];
int dfs(int u)
{
    int l=head[u].size();
    int i;
    for(i=0;i<l;++i)
    {
        int v=head[u][i];
        if(!vis[v])
        {
            vis[v]=1;
            if(match[v]==-1||dfs(match[v]))
            {
                match[v]=u;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{

    int u,v;
    int i;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;++i)match[i]=-1;
    while(m--)
    {
        scanf("%d%d",&u,&v);
        head[u].push_back(v);
    }
    int sum=0;
    for(i=1;i<=n;++i)
    {
        memset(vis,0,sizeof(vis));
        if(dfs(i))sum++;
    }
    printf("%d\n",sum);
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值