POJ 3041 Asteroids(模板——二分最大匹配(BFS增广))

题目链接:

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

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).

题意描述:

输入矩阵的大小和小行星的个数及坐标

计算并输出至少需要多少颗能量弹消灭掉所有的小行星

解题思路:

首先建立二分图,行和列为两个集合,有小行星的位置存入邻接矩阵为1,使用匈牙利算法,计算二分最大匹配,最后求的最小顶点覆盖。

AC代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 int n,k,e[510][510],pred[510],queue[250000],cx[510],cy[510];
 4 int maxmatch();
 5 int main()
 6 {
 7     int i,x,y;
 8     while(scanf("%d%d",&n,&k) != EOF)
 9     {
10         memset(e,0,sizeof(e));
11         for(i=1;i<=k;i++)
12         {
13             scanf("%d%d",&x,&y);
14             e[x][y]=1;
15         }
16         printf("%d\n",maxmatch());//输出最小顶点覆盖数
17     }
18     return 0;
19 }
20 int maxmatch()
21 {
22     int i,j,y;
23     int cur,tail,res=0;
24     memset(cx,0xff,sizeof(cx));
25     memset(cy,0xff,sizeof(cy));
26
27     for(i=1;i<=n;i++)
28     {
29         if(cx[i] != -1)//找到x集合中每个未盖点i进行一次找交错轨
30         continue;
31
32         for(j=1;j<=n;j++)
33             pred[j]=-2;//初始化为-2
34
35         cur=0;//队列初始化
36         tail=0;
37
38         for(j=1;j<=n;j++)//将i的邻接顶点加入队列
39         {
40             if(e[i][j])
41             {
42                 pred[j]=-1;//-1表示遍历到,是邻接顶点
43                 queue[tail++]=j;
44             }
45         }
46
47         while(cur < tail)//BFS
48         {
49             y=queue[cur];
50             if(cy[y]==-1)
51             break;//找到了一个未匹配的点,则找到了一条交错轨
52             cur++;
53             //已经匹配给cy[y]了,从cy[y]出发,将其邻接点加入队列
54             for(j=1;j<=n;j++)
55             {
56                 if(pred[j] == -2 && e[ cy[y ]][j])
57                 {
58                     pred[j]=y;
59                     queue[tail++]=j;
60                 }
61             }
62         }
63         if(cur == tail)//没有找到交错轨
64         continue;
65
66         while(pred[y] > -1)//更改交错轨上的匹配状态
67         {
68             cx[ cy[pred[y]] ] = y;
69             cy[y]=cy[ pred[y] ];
70             y=pred[y];
71         }
72         cy[y]=i;
73         cx[i]=y;
74
75         res++;//匹配数加1
76     }
77     return res;
78 }
时间: 2024-10-27 02:40:50

POJ 3041 Asteroids(模板——二分最大匹配(BFS增广))的相关文章

POJ 3041 Asteroids(二分匹配模板题)

题目链接:http://poj.org/problem?id=3041 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 l

POJ 3041 Asteroids 二分图之最大匹配

题意:在一个网格中有若干个点,每一次可以清除一行或者一列,问最少几次可以将网格中的点全部清除. 思路:这个题是一个入门的最大匹配题(这个好像不是思路..).一般的方式就是将 行 看作集合A,列 看作集合B. 这么说有点抽象.举个例子:2行3列的矩阵可以看作是集合A={1,2}与B={1,2,3},假设矩阵[1][2] 存在点(别忘了题意),则A中的元素1与B中元素2连有一条边. 这样就可以将题给矩阵转化为二分图,再利用匈牙利算法得到最大匹配数就是答案了. 1 #include<iostream>

poj 3041 Asteroids (二分图最大匹配 == 最小点覆盖数)

应该属于最基本的匹配问题,重点在于为什么可以把行和列化为二分图的左右两个集合,理解好长时间,可以尝试这样理解:一个炸弹只能炸掉一行 或着 一列,左右两个集合中的值分别代表某一行或着某一列,因为连线的意义是如果某一行某一列锁定的值有行星才连线,我们所要求的是最少的炸弹数即最少的行数和列数之和即选出最少的行数和列数从左右两个集合中,这些行和列满足的要求是能够覆盖所有的边,换句话说这些行和列的炸弹能够炸掉所有的行星.所以实质上就成了求最小的点集覆盖 == 最大匹配数. /*==============

POJ 3041 Asteroids (匈牙利算法)

Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14388 Accepted: 7828 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 astero

poj 3041——Asteroids

poj       3041——Asteroids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22604   Accepted: 12247 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 g

二分图匹配(匈牙利算法) POJ 3041 Asteroids

题目传送门 1 /* 2 题意:每次能消灭一行或一列的障碍物,要求最少的次数. 3 匈牙利算法:把行和列看做两个集合,当有障碍物连接时连一条边,问题转换为最小点覆盖数==二分图最大匹配数 4 趣味入门:http://blog.csdn.net/dark_scope/article/details/8880547 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 #include

POJ 3041 Asteroids (图论-最小点覆盖)

Asteroids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15079   Accepted: 8240 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 as

【网络流#6】POJ 3041 Asteroids 二分图最大匹配 - 《挑战程序设计竞赛》例题

学习网络流中ing...作为初学者练习是不可少的~~~构图方法因为书上很详细了,所以就简单说一说 把光束作为图的顶点,小行星当做连接顶点的边,建图,由于 最小顶点覆盖 等于 二分图最大匹配 ,因此求二分图最大匹配即可. 邻接矩阵,DFS寻找增广路,匈牙利算法 邻接矩阵:复杂度O(n^3) 如果使用邻接表:复杂度O(n*m) #include<cstdio> #include<cstring> #include<cmath> #include<iostream>

POJ 3041 Asteroids 二分图

原题连接:http://poj.org/problem?id=3041 Asteroids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17985   Accepted: 9798 Description Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <