Asteroids
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 12937 | Accepted: 7040 |
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.
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.
* 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).
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).
Source
1100 1010 1001 0000贪心求解的结果是4.而正确的结果是3.
重要定理: 二分图最小点覆盖数等于二分图的最大匹配数。
将横坐标视为n个独立的点,将纵坐标的值视为另外n个独立的点。
则每一个陨石可以视为一个匹配。
现在要求的就是 最小的点,可以将所有陨石都覆盖到。
用匈牙利算法求解如下:
提交记录:
1.样例未果。需要将横坐标处理为前n个点,纵坐标处理为n+纵坐标的值,也就是后n个点。同时, 需要修改模板中的0-V-1 为 0-V
2.Runtime Error。忘记修改MAXV的值了。。。网络流和 二分图算法尤其要注意最大的点个数。
3.Accepted!
#include
#include
#include
#include
#include
#include
#include
#define oo 1000000 #define MAXV 510*2//乘以2! using namespace std; int V, m; vector
G[MAXV]; int match[MAXV]; bool used[MAXV]; void add_edge(int u, int v) { G[u].push_back(v); G[v].push_back(u); } bool dfs(int v) { used[v] = true; for (int i = 0; i < G[v].size(); i++) { int u = G[v][i], w = match[u]; if (w < 0 || !used[w] && dfs(w)) { match[v] = u; match[u] = v; return true; } } return false; } int bipartite_matching() { int res = 0; int v; for (v = 0; v <= V; v++) match[v] = -1;//这两句修改为0-V。因为模板多一个结点实际上是没关系的。如果这个结点没有边相连,那也不会处理它 for (v = 0; v <= V; v++) { if (match[v] < 0) { memset(used, 0, sizeof(used)); if (dfs(v)) res++; } } return res; } int main() { cin >> V >> m; int i; for (i = 1; i <= m; i++) { int a, b; cin >> a >> b; add_edge(a, V + b); //注意这里!虽然都是坐标,从1-V,但横坐标和纵坐标是不同的点。所以结点的编号是不一样的!!!一定要区分开来 } V *= 2;//总坐标乘以2 cout << bipartite_matching() << endl;//二分图的最大匹配数等于二分图的最大点集覆盖数 return 0; }