您的位置:首页 > 其它

poj 3020 Antenna Placement 匈牙利二分匹配 最小覆盖数 !!!!

2012-02-15 20:37 459 查看
这道题只要建立起二分图就好说了,我们可以将*对应他周边的*,这样剑气二分图,所需最小的覆盖数=* 的数量-匹配数量/2;

#include<iostream>
using namespace std;
int map[500][500],vis[500],pa[500],v[500][500];
char a[500][500];
int n;
int find(int x)
{
for(int i=1;i<=n;i++)
{
if(!vis[i]&&map[x][i])
{
vis[i]=1;
if(pa[i]==-1||find(pa[i]))
{
pa[i]=x;
return 1;
}
}
}
return 0;
}
int dis[4][2]={1,0,0,1,-1,0,0,-1};//控制4方向
int main()
{
int cases,h,w;
while(cin>>cases)
{
while(cases--)
{
for(int i=0;i<500;i++)
{
for(int j=0;j<500;j++)
map[i][j]=0;
pa[i]=-1;
}
scanf("%d%d",&h,&w);
n=h*w;//这个n是二分匹配时搜索的范围
for(int i=0;i<h;i++)
scanf("%s",a[i]);
int cou=1;
for(int i=0;i<h;i++)//将*序列化存在v数组里
{
for(int j=0;j<w;j++)
{
if(a[i][j]=='*')
v[i][j]=cou++;
}
}
for(int i=0;i<h;i++)//下面建图的过程
{
for(int j=0;j<w;j++)
{
if(a[i][j]=='*')
{
for(int m=0;m<4;m++)
{
int mm=i+dis[m][1];
int nn=j+dis[m][0];
if(mm>=0&&mm<h&&nn>=0&&nn<w&&a[mm][nn]=='*')
{
map[v[i][j]][v[mm][nn]]=1;
}
}
}
}
}
int num=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(find(i))
num++;
}
//		cout<<cou<<" "<<num;
//	system("pause");
printf("%d\n",cou-1-num/2);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: