您的位置:首页 > 其它

POJ 3041-Asteroids-二分图匹配

2016-03-05 00:28 417 查看
题意:经典的二分图匹配问题。给出一个N*N矩阵,其中有K个障碍物。一发歼星炮可以清楚一行或者一列上的障碍物。求最少的开炮数。

做法:可以考虑最大点覆盖。建图左边顶点为行,右边顶点为列。若有障碍物则连边。此时最大点覆盖就是最小开炮数,也就是计算二分图最大匹配。使用匈牙利算法即可。

/*--------------------------------------------------------------------------------------*/
//        Helica's header
//        Second Edition
//        2015.11.7
//
#include <algorithm>
#include <iostream>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>

//debug function for a N*M array
#define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++)\
{for(int j=0;j<(M);j++){\
printf("%d",G[i][j]);}printf("\n");}
//debug function for int,float,double,etc.
#define debug_var(X) cout<<#X"="<<X<<endl;
/*--------------------------------------------------------------------------------------*/
using namespace std;

const int maxn = 500+10;
int uN,vN;
int G[2*maxn][2*maxn],linker[maxn];
bool used[maxn];

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

int hungary()
{
int res = 0;
memset(linker,-1,sizeof linker);
for(int u=1;u<=uN;u++)
{
memset(used,false,sizeof(used));
if(dfs(u)) res++;
}
return res;
}

int N,K,M,T;

int main()
{
while(~scanf("%d%d",&N,&K))
{
memset(G,0,sizeof G);
uN = vN = N;
for(int i=0;i<K;i++)
{
int x,y;
scanf("%d%d",&x,&y);
G[x][y] = 1;
}
printf("%d\n",hungary());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: