Antenna Placement--POJ 3020

1、题目类型:图论、最大二分匹配、匈牙利算法。

2、解题思路:(1)计算 '*' 的总数cnt,对每个 '*' 的上下左右进行遍历构建gra[][];(2)匈牙利算法求解最大点集覆盖的最大二分匹配;(3)用总数cnt减去匹配数除以2即为答案。

3、注意事项:注意gra[][]的大小。

4、实现方法:

#include<iostream>
using namespace std;

int cnt,ans;
int map[55][22],gra[500][500];
int vis[500],match[500];

void Init()
{
int n,m,i,j;
char ch;
memset(map,
0,sizeof(map));
memset(gra,
0,sizeof(gra));
cnt
=0;
cin
>>n>>m;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin
>>ch;
if(ch=='*')
map[i][j]
=++cnt;
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(map[i][j])
{
if(map[i][j+1])
gra[map[i][j]][map[i][j
+1]]=1;
if(map[i][j-1])
gra[map[i][j]][map[i][j
-1]]=1;
if(map[i+1][j])
gra[map[i][j]][map[i
+1][j]]=1;
if(map[i-1][j])
gra[map[i][j]][map[i
-1][j]]=1;
}
}
}
}

bool DFS(int s)
{
int i;
for(i=1;i<=cnt;i++)
{
if(gra[s][i]&&!vis[i])
{
vis[i]
=1;
if(match[i]==0||DFS(match[i]))
{
match[i]
=s;
return true;
}
}
}
return false;
}

void Hurry()
{
ans
=0;
int i;
memset(match,
0,sizeof(match));
for(i=1;i<=cnt;i++)
{
memset(vis,
0,sizeof(vis));
if(DFS(i))
ans
++;
}
}

int main()
{
int T;
cin
>>T;
while(T--)
{
Init();
Hurry();
cout
<<cnt-ans/2<<endl;
}
return 0;
}

 

posted @ 2010-08-19 21:24  勇泽  阅读(202)  评论(0编辑  收藏  举报