题目链接:http://poj.org/problem?id=3020
Description
Input
Output
Sample Input
2 7 9 ooo**oooo **oo*ooo* o*oo**o** ooooooooo *******oo o*o*oo*oo *******oo 10 1 * * * o * * * * * *
Sample Output
17 5
Source
题意:
一个矩形图中,有N个城市‘*’,这n个城市都要覆盖无线网络,若放置一个基站,那么它至多可以覆盖相邻的两个城市。
问最少需要放置多少个基站才能使所有的城市都覆盖无线?
PS:把原来的有向图G的每一个顶点都拆分为2个点,分别属于所要构造的二分图的两个顶点集里!
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAXN 517
int N;
int g[MAXN][MAXN], mm[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
int dx[4] = {-1,1,0,0};
int dy[4] = {0,0,1,-1};//四个方向
int dfs(int L)//从左边开始找增广路径
{
for(int R = 1 ; R <= N ; R++ )
{
if(g[L][R] && !used[R])
{
//找增广路,反向
used[R]=true;
if(linker[R] == -1 || dfs(linker[R]))
{
linker[R]=L;
return 1;
}
}
}
return 0;
}
int hungary()
{
int res = 0 ;
memset(linker,-1,sizeof(linker));
for(int L = 1; L <= N; L++)
{
memset(used,0,sizeof(used));
if(dfs(L))
res++;
}
return res;
}
void init()
{
memset(g,0,sizeof(g));
memset(mm,0,sizeof(mm));
}
int main()
{
int t;
char tt;
int n, m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
int p = 0;
for(int i = 1; i <= n; i++)
{
getchar();
for(int j = 1; j <= m; j++)
{
scanf("%c",&tt);
if(tt == '*')
mm[i][j] = ++p;
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
if(mm[i][j])
{
for(int k = 0; k < 4; k++)
{
int x = i+dx[k];
int y = j+dy[k];
if(mm[x][y])
g[mm[i][j]][mm[x][y]] = 1;
}
}
}
}
N = p;
int ans = p - hungary()/2;
printf("%d\n",ans);
}
return 0;
}
POJ 3020 Antenna Placement(二分匹配+拆点)
原文地址:http://blog.csdn.net/u012860063/article/details/39181831