您的位置:首页 > 其它

poj 3020 Antenna Placement(二分图的最大匹配)

2012-12-15 21:43 411 查看
题目:http://poj.org/problem?id=3020

这个题主要是构图比较难,处理方法是把城市编号然后如果在上下左右四个方向存在城市的话,那么这两个城市就可以组成一条边,构成的图是一个无向图,

DAG图的最小路径覆盖 = 节点数(n)- 最大匹配数;

无向图的最小路径覆盖=节点数(n)-最大匹配数/2;

代码:

View Code

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[405][405];
int st[45][15];
int vis[405];
int link[405];
int num;
int n,m;
int dire[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
int find(int x)
{
int i;
for(i=1;i<=num;i++)
{
if(!vis[i]&&map[x][i])
{
vis[i]=1;
if(link[i]==0||find(link[i]))
{
link[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
int t,i,j,k,su;
char c;
scanf("%d",&t);
while(t--)
{
memset(st,0,sizeof(st));
memset(map,0,sizeof(map));
memset(link,0,sizeof(link));
scanf("%d%d",&n,&m);
num=0;
getchar();
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%c",&c);
if(c=='*')
{
num++;
st[i][j]=num;
}
}
getchar();
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(st[i][j]!=0)
{
for(k=0;k<4;k++)
{
if(st[i+dire[k][0]][j+dire[k][1]]!=0)
{
map[st[i][j]][st[i+dire[k][0]][j+dire[k][1]]]=1;
}
}
}
}
}
su=0;
for(i=1;i<=num;i++)
{
memset(vis,0,sizeof(vis));
if(find(i))
su++;
}
printf("%d\n",num-(su/2));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: