POJ3041 二分图(性质)最小点覆盖等于最大匹配数(匈牙利模板题)

本文探讨了二分图的性质,包括最大匹配数等于最小覆盖数等关键概念,并通过一个具体的POJ题目示例介绍了如何应用这些理论解决实际问题。

二分图的性质

二分图中,点覆盖数是匹配数。
    (1) 二分图的最大匹配数等于最小覆盖数,即求最少的点使得每条边都至少和其中的一个点相关联,很显然直接取最大匹配的一段节点即可。
    (2) 二分图的独立数等于顶点数减去最大匹配数,很显然的把最大匹配两端的点都从顶点集中去掉这个时候剩余的点是独立集,这是|V|-2*|M|,同时必然可以从每条匹配边的两端取一个点加入独立集并且保持其独立集性质。
    (3) DAG的最小路径覆盖,将每个点拆点后作最大匹配,结果为n-m,求具体路径的时候顺着匹配边走就可以,匹配边i→j',j→k',k→l'....构成一条有向路径。

     (4)最大匹配数=左边匹配点+右边未匹配点。因为在最大匹配集中的任意一条边,如果他的左边没标记,右边被标记了,那么我们就可找到一条新的增广路,所以每一条边都至少被一个点覆盖。

     (5)最小边覆盖=图中点的个数-最大匹配数=最大独立集。

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

Asteroids
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 23262 Accepted: 12611

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

题意:给出n*n矩阵,并且给出障碍物坐标,让你求最小的武器使用次数消灭所有障碍。
思路:以行列分别代表一个点集,形成二分图,在利用最小点覆盖在二分图中等于最大匹配数套用匈牙利模板。

Code:
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
const int AX = 500+66;
int n,k;
int g[AX][AX];
int used[AX];
int linker[AX];

bool dfs( int u ){
	int v;
	for( v = 1 ; v <= n ; v++ ){
		if( !used[v] && g[u][v] ){
			used[v] = 1;
			if( linker[v] == -1 || dfs(linker[v]) ){
				linker[v] = u;
				return true;
			}
		}
	}
	return false;
}

int xyl(){
	int ans = 0;
	int u;
	memset(linker,-1,sizeof(linker));
	for( u = 1 ; u <= n ;u ++ ){
		memset(used,0,sizeof(used));
		if( dfs(u) ) ans ++;
	}
	return ans;
}

int main(){

	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>k;
	int x,y;
	for( int i = 0 ; i < k ; i++ ){
		cin>>x>>y;
		g[x][y] = 1;
	}
	cout<<xyl()<<endl;

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值