您的位置:首页 > 其它

【bzoj3175】[Tjoi2013]攻击装置

2016-08-11 15:21 387 查看
每两个能互相攻击且能放置的点连一条双向边,然后跑二分图最大点独立集即可

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

typedef long long LL;

#define M 80010
#define N 210

struct edge
{
int to,next;
}e[M<<1];
int head[M<<1];
int cnt;

int ly[M];

int a

,flag[M];

char s
;

int dx[]={1,1,2,2};
int dy[]={2,-2,1,-1};

int n,q;
int tot,ans;

void link(int x,int y)
{
e[++cnt]=(edge){y,head[x]};
head[x]=cnt;
}

bool find(int x)
{
for (int i=head[x];i;i=e[i].next)
{
int t=e[i].to;
if (flag[t]!=q)
{
flag[t]=q;
if (!ly[t] || find(ly[t]))
{
ly[t]=x;
return true;
}
}
}
return false;
}

int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%s",s+1);
for (int j=1;j<=n;j++)
if (s[j]=='0')
a[i][j]=++tot;
else
a[i][j]=0;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (a[i][j])
for (int k=0;k<4;k++)
{
int x=i+dx[k],y=j+dy[k];
if (x<1 || x>n || y<1 || y>n)
continue;
if (a[x][y])
link(a[i][j],a[x][y]),link(a[x][y],a[i][j]);
}
for (int i=1;i<=tot;i++)
{
q++;
if (find(i))
ans++;
}
printf("%d\n",tot-ans/2);
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: