您的位置:首页 > 编程语言 > C语言/C++

POJ 3020Antenna Placement(二分最大匹配之最大匹配)

2014-06-05 18:31 381 查看
题目地址:http://poj.org/problem?id=3020

题目很简单,最大匹配。先进行黑白染色(后来才发现原来那种按照横纵坐标之和的奇偶性匹配的方法叫做黑白染色。。),然后匹配。只需要在最后的时候求出最大匹配,然后再把剩下的单个的加上就是最终答案。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include<algorithm>
using namespace std;
int tu[50][50], mp[500][500], vis[500], link[500], k1, k2, a[500], b[500];
int jx[]= {0,0,1,-1};
int jy[]= {1,-1,0,0};
int dfs(int x)
{
int i;
for(i=0; i<k2; i++)
{
if(!vis[i]&&mp[x][b[i]])
{
vis[i]=1;
if(link[b[i]]==-1||dfs(link[b[i]]))
{
link[b[i]]=x;
return 1;
}
}
}
return 0;
}
void hungary(int k0)
{
int i, ans=0;
memset(link,-1,sizeof(link));
for(i=0; i<k1; i++)
{
memset(vis,0,sizeof(vis));
if(dfs(a[i]))
ans++;
}
printf("%d\n",k0-ans);
}
int main()
{
int t, m, n, i, j, k, k0;
char s[100];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
getchar();
k0=0;
for(i=0; i<n; i++)
{
scanf("%s",s);
for(j=0; j<m; j++)
{
if(s[j]=='o')
tu[i][j]=0;
else
{
tu[i][j]=1;
k0++;
}
}
}
k1=k2=0;
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if(tu[i][j])
{
if((i+j)%2==0)
{
a[k1++]=m*i+j;
}
else
b[k2++]=m*i+j;
}
}
}
memset(mp,0,sizeof(mp));
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if(tu[i][j])
{
for(k=0; k<4; k++)
{
int a=i+jx[k];
int b=j+jy[k];
if(a>=0&&b>=0&&a<n&&b<m&&tu[a][b])
{
mp[m*i+j][m*a+b]=1;
}
}
}
}
}
hungary(k0);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息