POJ 3041 Asteroids 二分图之最大匹配

题意:在一个网格中有若干个点,每一次可以清除一行或者一列,问最少几次可以将网格中的点全部清除。

思路:这个题是一个入门的最大匹配题(这个好像不是思路..)。一般的方式就是将 行 看作集合A,列 看作集合B。

这么说有点抽象。举个例子:2行3列的矩阵可以看作是集合A={1,2}与B={1,2,3},假设矩阵[1][2] 存在点(别忘了题意),则A中的元素1与B中元素2连有一条边。

这样就可以将题给矩阵转化为二分图,再利用匈牙利算法得到最大匹配数就是答案了。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int n, k;
 5 int v1, v2;//二分图顶点集,都等于n
 6 bool map[501][501];
 7 bool visit[501]; //记录v2中的每个点是否被搜索过
 8 int link[501]; //记录v2中的点y在v1中所匹配的点x的编号
 9 int result;//最大匹配数
10 bool dfs(int x)
11
12 {
13     for (int y = 1; y <= v2; y++)
14     {
15         if (map[x][y] && !visit[y])
16         {
17             visit[y] = true;
18             if (link[y] == 0 || dfs(link[y]))
19             {
20                 link[y] = x;
21                 return 1;
22             }
23         }
24     }
25     return 0;
26 }
27
28 //匈牙利算法hungary algorithm
29 void search()
30 {
31     for (int x = 1; x <= v1; x++)
32     {
33
34         memset(visit,false,sizeof(visit));
35
36         if (dfs(x)) //从v1中的节点x开始寻找增广路径p
37
38             result++;
39     }
40 }
41
42 int main()
43 {
44     cin >> n >> k;
45     v1 = v2 = n;
46     int x, y;
47     memset(map,0,sizeof(map));
48     for (int i = 1; i <= k; i++)
49     {
50         cin >> x >> y;
51         map[x][y] = true;
52     }
53     search();
54     cout << result << endl;
55     return 0;
56 }

原文地址:https://www.cnblogs.com/llllrj/p/9398378.html

时间: 2024-10-12 20:13:37

POJ 3041 Asteroids 二分图之最大匹配的相关文章

poj - 3041 Asteroids (二分图最大匹配+匈牙利算法)

http://poj.org/problem?id=3041 在n*n的网格中有K颗小行星,小行星i的位置是(Ri,Ci),现在有一个强有力的武器能够用一发光速将一整行或一整列的小行星轰为灰烬,想要利用这个武器摧毁所有的小行星最少需要几发光束. 主要是构图,将每一行当成一个点,构成集合1,每一列也当成一个点,构成集合2,每一个障碍物的位置坐标将集合1和集合2的点连接起来,也就是将每一个障碍物作为连接节点的边,这样可以得出本题是一个最小点覆盖的问题==二分图的最大匹配. 就可以通过匈牙利算法求解.

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 <

【网络流#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 在一个n*n的地图中,有m和障碍物,你每一次可以消除一行或者一列的障碍物,问你最少消除几次可以将障碍物全部清除. 用二分图将行(左边)和列(右边)用障碍物联系起来,比如(2,3)有个障碍物,那么左边的2和右边的3连边.边的个数就是障碍物的个数,点的个数就是次数,所以问题就变成了用少的点覆盖全部的边,也就是最小点覆盖问题.二分图中,最小点覆盖=最大匹配数. 1 //最小点覆盖 = 最大匹配 2 #include <iostre

POJ 3041 Asteroids(二分图模板题)

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

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

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

二分图匹配(匈牙利算法) 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: 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