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;
}