首页 > 代码库 > EOJ 2069 Asteroids 二分图最大匹配

EOJ 2069 Asteroids 二分图最大匹配

Description
Bessie wants to navigate her spaceship through a dangerous asteroid field inthe 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 pointsof the grid.
Fortunately, Bessie has a powerful weapon that can vaporize all the asteroidsin any given row or column of the grid with a single shot.This weapon is quiteexpensive, so she wishes to use it sparingly.Given the location of all theasteroids in the field, find the minimum number of shots Bessie needs to fireto 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 mustshoot.

Sample Input
3 4
1 1
1 3
2 2
3 2

Sample Output
2
INPUT DETAILS:
The following diagram represents the data, where "X" is an asteroidand "." 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), andthen she may fire down column 2 to destroy the asteroids at (2,2) and (3,2).

 

 

 

 

题目分析:将目标点的横坐标和纵坐标作为两个集合,则一个目标就是一条边,一枪可以消灭与这个点邻接的所有边,故求一个图的最小点覆盖即可,亦即二分图最大匹配数。

用匈牙利算法找增广路径。用dfs实现,初始化所有点为未盖点。依次搜索每一个点,如果存在增广路,则匹配数加1;

 

 

 

 

 

AC代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <string>

#include <vector>

#include <map>

#include <algorithm>

 

using namespace std;

const int MAXN=505;

vector<int> g[MAXN]; //邻接表储存图

int n,m;

bool vis[505];//标记点

int link[MAXN];//匹配关系,初始化为-1

bool dfs(int s){

   for(int i=0;i<g[s].size();++i){

       int u=g[s][i];

       if(vis[u]) continue;

       vis[u]=true;

       if(link[u]==-1 || dfs(link[u])){//u未覆盖,或u的匹配邻接未盖点

           link[u]=s;

           return true;

       }

    }

   return false;

}

 

int hungry(){

   int ans=0;

   memset(link,-1,sizeof(link));//初始化每个点未覆盖

   for(int i=1;i<=n;++i){

       memset(vis,false,sizeof(vis));

       if(dfs(i))  ans++;//存在增广路径,且每次增广路径长度比匹配数大一

    }

   return ans;

}

 

int main()

{

   scanf("%d%d",&n,&m);

   for(int i=1;i<=n;++i)

       g[i].clear();

   for(int i=0;i<m;++i){

       int x,y;

       scanf("%d%d",&x,&y);

       g[x].push_back(y);

    }

   printf("%d\n",hungry());

   return 0;

}

 

 

 

 

 

 

EOJ 2069 Asteroids 二分图最大匹配