标签:bzoj bzoj3175 二分图最大匹配 匈牙利算法
题目大意:给定一个n*n的网格图,要在0的位置上放置一些攻击装置,其中一个攻击装置的攻击范围是周围8个“日”字形区域,要求不能互相攻击,求最多放置多少个攻击装置
每两个能互相攻击且能放置的点连一条双向边,然后跑二分图最大点独立集即可
4W个点n^2居然没TLE 是数据太弱还是匈牙利算法太强了?
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 210
using namespace std;
struct abcd{
int to,next;
}table[M*M<<3];
int head[M*M],tot;
int n,m,ans;
int map[M][M];
int state[M*M],result[M*M],T;
const int dx[]={1,1,2,2};
const int dy[]={2,-2,1,-1};
void Add(int x,int y)
{
table[++tot].to=y;
table[tot].next=head[x];
head[x]=tot;
}
bool Hungary(int x)
{
int i;
for(i=head[x];i;i=table[i].next)
{
if(state[table[i].to]==T)
continue;
state[table[i].to]=T;
if( !result[table[i].to] || Hungary(result[table[i].to]) )
{
result[table[i].to]=x;
return true;
}
}
return false;
}
int main()
{
int i,j,k;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%1d",&map[i][j]);
if(map[i][j]==1)
map[i][j]=-1;
else
map[i][j]=++m;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(~map[i][j])
for(k=0;k<4;k++)
{
int xx=i+dx[k];
int yy=j+dy[k];
if(xx<=0||yy<=0||xx>n||yy>n)
continue;
if(map[xx][yy]==-1)
continue;
Add(map[i][j],map[xx][yy]);
Add(map[xx][yy],map[i][j]);
}
ans=m<<1;
for(i=1;i<=m;i++)
{
++T;
if( Hungary(i) )
--ans;
}
cout<<(ans>>1)<<endl;
}
BZOJ 3175 Tjoi2013 攻击装置 二分图最大匹配
标签:bzoj bzoj3175 二分图最大匹配 匈牙利算法
原文地址:http://blog.csdn.net/popoqqq/article/details/40890351