Description

给定一个01矩阵,其中你可以在0的位置放置攻击装置。每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y-1),(x+1,y-2),(x+2,y-1),(x-1,y+2),(x-2,y+1), (x+1,y+2),(x+2,y+1)

求在装置互不攻击的情况下,最多可以放置多少个装置。

Input

第一行一个整数N,表示矩阵大小为N*N。接下来N行每一行一个长度N的01串,表示矩阵。

Output

一个整数,表示在装置互不攻击的情况下最多可以放置多少个装置。

Sample Input

3

010

000

100

Sample Output

4

HINT

100%数据 N<=200

Solution

一个点向所有它能打到的点连边

由于日字步两点的和的奇偶性一定不同,所以图可以二分

要求的就是最大独立集,可用点数-最大匹配

所以做一遍Dinic就行了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=200+10,inf=0x3f3f3f3f;
int e=1,n,to[MAXN*MAXN*16],nex[MAXN*MAXN*16],cap[MAXN*MAXN*16],beg[MAXN*MAXN],level[MAXN*MAXN],s,t,dr[4][2]={{1,-2},{2,-1},{1,2},{2,1}},pres[MAXN*MAXN],prex[MAXN*MAXN],cnt,cur[MAXN*MAXN];
char str[MAXN];
std::queue<int> q;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline int id(int x,int y)
{
return (x-1)*n+y;
}
inline void insert(int x,int y,int z)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
cap[e]=z;
to[++e]=x;
nex[e]=beg[y];
beg[y]=e;
cap[e]=0;
}
inline void match(int x,int y)
{
for(register int i=0;i<4;++i)
{
int dx=x+dr[i][0],dy=y+dr[i][1];
if(dx<1||dx>n||dy<1||dy>n)continue;
if((x+y)&1)insert(id(x,y),id(dx,dy),1);
else insert(id(dx,dy),id(x,y),1);
}
}
inline bool bfs()
{
memset(level,0,sizeof(level));
level[s]=1;
q.push(s);
while(!q.empty())
{
int x=q.front();
q.pop();
for(register int i=beg[x];i;i=nex[i])
if(!level[to[i]]&&cap[i])level[to[i]]=level[x]+1,q.push(to[i]);
}
return level[t];
}
inline int dfs(int x,int maxflow)
{
if(!maxflow||x==t)return maxflow;
int res=0,f;
for(register int &i=cur[x];i;i=nex[i])
if(cap[i]&&level[to[i]]==level[x]+1)
{
f=dfs(to[i],min(maxflow,cap[i]));
cap[i]-=f;
cap[i^1]+=f;
maxflow-=f;
res+=f;
if(!maxflow)break;
}
return res;
}
inline int Dinic()
{
int res=0;
while(bfs())memcpy(cur,beg,sizeof(cur)),res+=dfs(s,inf);
return res;
}
int main()
{
read(n);
s=n*n+1,t=s+1;
for(register int i=1;i<=n;++i)
{
scanf("%s",str+1);
for(register int j=1;j<=n;++j)
if(str[j]=='0')
{
cnt++;
match(i,j);
if((i+j)&1)insert(s,id(i,j),1);
else insert(id(i,j),t,1);
}
}
write(cnt-Dinic(),' ');
return 0;
}

最新文章

  1. hadoop1.2.1伪分布模式配置
  2. PotPlayer 1.6.52965 美化版|视频播放器
  3. [LeetCode] Range Sum Query - Immutable &amp; Range Sum Query 2D - Immutable
  4. 斐波那契堆(二)之 C++的实现
  5. PHP函数补完:stream_context_create()模拟POST/GET
  6. hdu4924 Football Manager
  7. Photoshop Cs5 64位系统破解版下载(内含破解方法)
  8. aspxgridView,Repeater增加自动序号列
  9. centos SSH配置详解
  10. PAT (Advanced Level) 1079. Total Sales of Supply Chain (25)
  11. guava缓存底层实现
  12. sudo用法
  13. js 对象,数组,字符串,相互转换
  14. session的一些笔记
  15. java对象的四种引用:强引用、软引用、弱引用和虚引用
  16. 机器学习系列-tensorflow-02-基本操作运算
  17. Android平台上最好的几款免费的代码编辑器
  18. 设计模式--策略模式(strategy)
  19. 3dmax fx shader, vertex color
  20. css-box-shadow

热门文章

  1. vijos p1027休息中的小呆
  2. python中- \r用法
  3. 开胃小菜——impress.js代码详解
  4. andriod学习二 设置开发环境
  5. hdu1596find the safest road(floyd)
  6. Selenium 入门到精通系列:六
  7. Siki_Unity_1-9_Unity2D游戏开发_Roguelike拾荒者
  8. C 计算员工工资
  9. centos 6.5 启动时卡在进度条位置无法进入系统解决办法。
  10. 告别加载dll 出错开机加载项大揭秘