POJ3041 Asteroids【二分图最小点覆盖】

题目链接:

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

题目大意:

有一个N*N的矩阵,有些格子上有障碍物(坐标为(x,y) ),在消除这些障碍物的时候,可以一次性消除

该障碍物同一行所有的障碍物,或是一次性消除该障碍物同一列所有的障碍物。只能选择清理该行或是

清理该列。问:最小进行多少次消除,就可以清理所有的障碍物。

思路:

可以将每一行当做一个点,这样总共有N个点,作为二分图的一边。将每一列当做一个点,这样又有N

个点,作为二分图的另一边。将有障碍物的行点和列点连接起来,每次只能选择行或是列,需要清除所

有的障碍物。所以不能存在一条边两边的点都没有被选中的情况。这样问题就转变为选择最少的一些点

(行点或是列点),使得从这些点与所有的边相连,也就是二分图最小点覆盖问题。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN = 550;

bool Map[MAXN][MAXN],Mask[MAXN];

int NX,NY;
int cx[MAXN],cy[MAXN];

int FindPath(int u)
{
    for(int i = 1; i <= NY; ++i)
    {
        if(Map[u][i] && !Mask[i])
        {
            Mask[i] = 1;
            if(cy[i] == -1 || FindPath(cy[i]))
            {
                cy[i] = u;
                cx[u] = i;
                return 1;
            }
        }
    }
    return 0;
}

int MaxMatch()
{
    for(int i = 1; i <= NX; ++i)
        cx[i] = -1;
    for(int i = 1; i <= NY; ++i)
        cy[i] = -1;

    int res = 0;
    for(int i = 1; i <= NX; ++i)
    {
        if(cx[i] == -1)
        {
            for(int j = 1; j <= NY; ++j)
                Mask[j] = 0;
            res += FindPath(i);
        }
    }
    return res;
}

int main()
{
    int N,M,u,v;
    while(~scanf("%d%d",&N,&M))
    {
        NX = NY = N;
        memset(Map,0,sizeof(Map));
        for(int i = 1; i <= M; ++i)
        {
            scanf("%d%d",&u,&v);
            Map[u][v] = 1;
        }
        printf("%d\n",MaxMatch());
    }

    return 0;
}
时间: 2024-07-31 10:23:01

POJ3041 Asteroids【二分图最小点覆盖】的相关文章

POJ3041 Asteroids(二分图最小点覆盖)

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

POJ 3041 Asteroids (二分图最小点覆盖)

题目链接:http://poj.org/problem?id=3041 在一个n*n的地图中,有m和障碍物,你每一次可以消除一行或者一列的障碍物,问你最少消除几次可以将障碍物全部清除. 用二分图将行(左边)和列(右边)用障碍物联系起来,比如(2,3)有个障碍物,那么左边的2和右边的3连边.边的个数就是障碍物的个数,点的个数就是次数,所以问题就变成了用少的点覆盖全部的边,也就是最小点覆盖问题.二分图中,最小点覆盖=最大匹配数. 1 //最小点覆盖 = 最大匹配 2 #include <iostre

[POJ3041] Asteroids(最小点覆盖-匈牙利算法)

传送门 题意: 给一个N*N的矩阵,有些格子有障碍,要求我们消除这些障碍,问每次消除一行或一列的障碍,最少要几次. 解析: 把每一行与每一列当做二分图两边的点. 某格子有障碍,则对应行与列连边. 选出最少的点,使得所有边被覆盖. 最小点覆盖. ——代码 1 #include <cstdio> 2 #include <cstring> 3 #define M(x, a) memset(a, x, sizeof(a)) 4 5 using namespace std; 6 7 cons

POJ - 3041 Asteroids 二分图 最小点覆盖

题目大意:在一个N * N的网格中,有M个障碍物,现在你有一把武器,这个武器可以消除任意一行或者一列的障碍物,现在要求将所有障碍物消完,问至少使用这把武器多少次 解题思路:想了老半天怎么解决行和列的问题...怎么表示两个点集 最后突然想到,既然不知道怎么处理行列,就将行列分别分成两个点集吧,点就代表行和列之间的关系,就这样交了一发,A了. 其实,这确实是,行列之间的连线(点)只要能用某些点表示就可以了.那些点就是所有连线的其中一个端点,这样这些点就能画出所有的连线了,所有的连线都能被表示到了,就

Asteroids POJ - 3041 二分图最小点覆盖

Asteroids POJ - 3041 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 point

HDU2119_Matrix(二分图/最小点覆盖=最大匹配)

解题报告 题目传送门 题意: 题意类似与POJ3041 思路: 见POJ3041解题报告 最小点覆盖. #include <iostream> #include <cstring> #include <cstdio> using namespace std; int mmap[110][110],vis[110],pre[110],n,m; int dfs(int x) { for(int i=1; i<=m; i++) { if(!vis[i]&&

HDU1498_50 years, 50 colors(二分图/最小点覆盖=最大匹配)

解题报告 题意: 给你一个矩阵,矩阵里面是气球,气球有1-50种颜色,问你在k次之内能不能把那种存在的颜色消掉(每种颜色k次机会),不能消掉的颜色按升序输出. 思路: 白想一上午了,理解错了题意,原来每种有k次可以消除的机会,还以为是总共k次机会消气球. 理解对了就很好做,类似POJ3041 求最小点覆盖.用最少的点覆盖最多的边. 每次枚举颜色看是否操作次数超过k次. 英语.................... ...................... #include <iostream

POJ2226 Muddy Fields(二分图最小点覆盖集)

题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作为XY部,每一块泥地看作边.这样就构造出了一个二分图. 那么,问题就是在这个二分图中就是选出最少的点覆盖所有的边,即二分图最小点覆盖集,而二分图最小点覆盖集=二分图最大匹配. 1 #include<cstdio> 2 #include<cstring> 3 #include<qu

hihoCoder #1127 : 二分图二&#183;二分图最小点覆盖和最大独立集

#1127 : 二分图二·二分图最小点覆盖和最大独立集 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上次安排完相亲之后又过了挺长时间,大家好像都差不多见过面了.不过相亲这个事不是说那么容易的,所以Nettle的姑姑打算收集一下之前的情况并再安排一次相亲.所以现在摆在Nettle面前的有2个问题: 1.姑姑想要了解之前所有相亲的情况.对于任一个一次相亲,只要跟参与相亲的两人交流就可以得到这次相亲的情况.如果一个人