[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 const int MAXN = 501;
 8 int n, k, cnt, ans;
 9 int head[MAXN], next[MAXN * MAXN], to[MAXN * MAXN], belong[MAXN];
10 bool vis[MAXN];
11
12 inline void add(int x, int y)
13 {
14     to[cnt] = y;
15     next[cnt] = head[x];
16     head[x] = cnt++;
17 }
18
19 inline bool find(int u)
20 {
21     int i, v;
22     for(i = head[u]; i != -1; i = next[i])
23     {
24         v = to[i];
25         if(!vis[v])
26         {
27             vis[v] = 1;
28             if(!belong[v] || find(belong[v]))
29             {
30                 belong[v] = u;
31                 return 1;
32             }
33         }
34     }
35     return 0;
36 }
37
38 int main()
39 {
40     int i, x, y;
41     scanf("%d %d", &n, &k);
42     M(-1, head);
43     for(i = 1; i <= k; i++)
44     {
45         scanf("%d %d", &x, &y);
46         add(x, y);
47     }
48     for(i = 1; i <= n; i++)
49     {
50         M(0, vis);
51         if(find(i)) ans++;
52     }
53     printf("%d", ans);
54     return 0;
55 }

时间: 2024-10-16 21:01:30

[POJ3041] Asteroids(最小点覆盖-匈牙利算法)的相关文章

poj3041 Asteroids --- 最小点覆盖

#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<queue> const int maxn=510; using namespace std; int my[maxn],mx[maxn],vis[maxn],e[maxn][maxn],n;

POJ 3041 Asteroids(二分图 &amp;&amp; 匈牙利算法 &amp;&amp; 最小点覆盖)

嗯... 题目链接:http://poj.org/problem?id=3041 这道题的思想比较奇特: 把x坐标.y坐标分别看成是二分图两边的点,如果(x,y)上有行星,则将(x,y)之间连一条边,而我们要做的就是要找尽量少的点把所有的边覆盖,即为最小点覆盖问题,根据König定理:最小覆盖点数=最大匹配数,所以就可以用匈牙利算法求最大匹配了. AC代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream&

Asteroids POJ - 3041 匈牙利算法+最小点覆盖K&#246;nig定理

题意: 给出一个N*N的地图N   地图里面有K个障碍     你每次可以选择一条直线 消除这条直线上的所有障碍  (直线只能和列和行平行) 问最少要消除几次 题解: 如果(x,y)上有一个障碍 则把X加入点集 V1 .Y加入点集V2   并且X Y连一条边  这样构成一个新图 如果选择 V1中的点 X 那么就相当于消去 (X,y)中的所有Y    要找使最小点覆盖 那就是跑一遍 匈牙利就行了 详细证明见二分图最小点覆盖K?nig定理 其中 x y需要连单向边 不然会造成混乱 因为x=1 y=1

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: 17543   Accepted: 9548 Description Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <

【POJ 3041】Asteroids (最小点覆盖)

每次选择清除一行或者一列上的小行星.最少选择几次. 将行和列抽象成点,第i行为节点i+n,第j列为节点j,每个行星则是一条边,连接了所在的行列. 于是问题转化成最小点覆盖.二分图的最小点覆盖==最大匹配. #include <cstdio> #include <cstring> const int N=505<<1; int n,vis[N],link[N],g[N][N]; int find(int u) { for(int i=1; i<=n*2; i++)

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

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

ACM/ICPC 之 机器调度-匈牙利算法解最小点覆盖集(DFS)(POJ1325)

//匈牙利算法-DFS //求最小点覆盖集 == 求最大匹配 //Time:0Ms Memory:208K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MAX 105 #define INF 0x3f3f3f3f int n,m,k; int gp[MAX][MAX]; bool sx[MAX],s

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