题目描述

给定一个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)
求在装置互不攻击的情况下,最多可以放置多少个装置。

输入

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

输出

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

样例输入

3
010
000
100

样例输出

4

提示

100%数据 N<=200

  将矩阵黑白染色(就是相邻格子染不同颜色),可以发现每个攻击装置能攻击到的格子和它所在格子染色不同,将源点连向白色格子,黑色格子连向汇点,每个白点连向能攻击到的黑点,跑二分图最大匹配,然后用总格子数-最大匹配-矩阵中1的个数。这个为什么是对的?因为相连的点表示能互相攻击到,去掉二分图最大匹配的边之后剩下的点之间一定不相连就一定不会互相攻击到。同时给这个残留的二分图加上之前任何一个删除的点都会有匹配边,所以这样是最大的。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int next[1000001];
int to[1000001];
int val[1000001];
int head[1000001];
int tot=1;
int q[100001];
int n,k;
int S,T;
int ans=0;
int x,y;
int d[100001];
char s[1001][1001];
int c[1001][1001];
const int dx[]={-2,-1,1,2,2,1,-1,-2};
const int dy[]={1,2,2,1,-1,-2,-2,-1};
void add(int x,int y,int v)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
val[tot]=v;
tot++;
next[tot]=head[y];
head[y]=tot;
to[tot]=x;
val[tot]=0;
}
bool bfs(int S,int T)
{
int r=0;
int l=0;
memset(q,0,sizeof(q));
memset(d,-1,sizeof(d));
q[r++]=S;
d[S]=0;
while(l<r)
{
int now=q[l];
for(int i=head[now];i;i=next[i])
{
if(d[to[i]]==-1&&val[i]!=0)
{
d[to[i]]=d[now]+1;
q[r++]=to[i];
}
}
l++;
}
if(d[T]==-1)
{
return false;
}
else
{
return true;
}
}
int dfs(int x,int flow)
{
if(x==T)
{
return flow;
}
int now_flow;
int used=0;
for(int i=head[x];i;i=next[i])
{
if(d[to[i]]==d[x]+1&&val[i]!=0)
{
now_flow=dfs(to[i],min(flow-used,val[i]));
val[i]-=now_flow;
val[i^1]+=now_flow;
used+=now_flow;
if(now_flow==flow)
{
return flow;
}
}
}
if(used==0)
{
d[x]=-1;
}
return used;
}
void dinic()
{
while(bfs(S,T)==true)
{
ans+=dfs(S,0x3f3f3f);
}
}
int main()
{
scanf("%d",&n);
S=n*n+1;
T=n*n+2;
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(s[i][j]=='0')
{
c[i][j]=(i-1)*n+j;
if((i+j)%2==0)
{
add(S,c[i][j],1);
}
else
{
add(c[i][j],T,1);
}
}
else
{
k++;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(s[i][j]!='1'&&(i+j)%2==0)
{
for(int m=0;m<=7;m++)
{
int fx=dx[m]+i;
int fy=dy[m]+j;
if(fx>0&&fx<=n&&fy>0&&fy<=n&&c[fx][fy]!=-1)
{
add(c[i][j],c[fx][fy],0x3f3f3f);
}
}
}
}
}
dinic();
printf("%d",n*n-k-ans);
}

BZOJ3175[Tjoi2013]攻击装置——二分图最大独立集的更多相关文章

  1. BZOJ3175:[TJOI2013]攻击装置(二分图最大独立集)

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

  2. bzoj4808: 马 & bzoj3175: [Tjoi2013]攻击装置 (黑白染色+最小割)

    bzoj4808: 马 & bzoj3175: [Tjoi2013]攻击装置 题目:传送门 简要题意: 和n皇后问题差不多,但是这里是每个棋子走日子,而且有些格子不能放棋子.求最多能放多少个棋 ...

  3. BZOJ3175: [Tjoi2013]攻击装置

    题解: 最大点独立集...好像水过头了... 不过发现我二分图好像忘完了!!! 代码: #include<cstdio> #include<cstdlib> #include& ...

  4. 【BZOJ 3175】 3175: [Tjoi2013]攻击装置(二分图匹配)

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

  5. BZOJ3175 Tjoi2013 攻击装置(二分图匹配)

    传送门 Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照"日"字攻击其周围的 8个位置(x-1,y-2),(x-2,y ...

  6. [TJOI2013] 攻击装置 - 二分图匹配

    给定 \(N \times N\) 棋盘,某些格子是障碍,问可以放置的互不侵犯的马的个数 黑白染色后建立二分图,求最大独立集 = 总点数 - 最大匹配数 注意把反边也连上会WA掉(脑抽一发血) #in ...

  7. bzoj3175: [Tjoi2013]攻击装置&&4808: 马

    终于知道为啥网络流这么受欢迎了. 其实就是构个图模板一下的事儿,比较好打是吧. 然后这题网络流黑白染色(其实感觉上匈牙利更加直接好想啊,但是实际上黑白染色给人感觉就是二分图) st连白而ed连黑,流量 ...

  8. BZOJ_3175_[Tjoi2013]攻击装置_二分图匹配

    BZOJ_3175_[Tjoi2013]攻击装置_二分图匹配Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置 ...

  9. 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】

    P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...

随机推荐

  1. QT listwiget 控件添加图片

    很多的时候我们需要制作类似手机的中的电子相框, 可以用listwidget 控件实现 直接上代码 MainWindow::MainWindow(QWidget *parent) : QMainWind ...

  2. 使用systemctl报错(centos 7)

    服务器运行210多天,今天使用systemctl准备重启下sshd发现报错,如上图. systemctl restart.stop.status.start等所有操作都报错.原因未知. 在此之前有内存 ...

  3. svn 从文件上次修改以来没有任何文件修改或加入。

    现象:代码已经被修改过了,但是再往svn上提交代码时仍然提示: 从文件上次修改以来没有任何文件修改或加入. 解决办法: 1.找打存放代码的文件夹,右键——TortoiseSVN——clean up(清 ...

  4. Luogu4249 WC2007 石头剪刀布 费用流

    传送门 考虑竞赛图三元环计数,设第\(i\)个点的入度为\(d_i\),根据容斥,答案为\(C_n^3 - \sum C_{d_i}^2\) 所以我们需要最小化\(\sum C_{d_i}^2\) 考 ...

  5. Idea Live Template代码片段总结

    目录 Idea Live Template总结 一.演示 二.详细介绍 2.1 类型 2.2设置(win默认快捷键win+alt+s) 2.3 快捷键 2.4 实战 Idea Live Templat ...

  6. Spring Boot 进行Bean Validate和Method Validate

    SpringBoot在内部通过集成hibernate-validation 已经实现了JSR-349验证规范接口,在SpringBoot项目中只要直接使用就行了. 一般用在Controller中用于验 ...

  7. [JSOI2016]病毒感染[dp]

    题意 有 \(n​\) 个村庄按标号排列,每个村庄有一个死亡速度 \(a_i​\) 表示每天死 \(a_i​\) 人(除非你治好这个村庄). 你从 1 号村庄出发,每天可以选择向相邻的村庄进发或者治愈 ...

  8. .net core实践系列之短信服务-为什么选择.net core(开篇)

    前言 从今天我将会写.net core实战系列,以我最近完成的短信服务作为例子.该系列将会尽量以最短的时间全部发布出来.源码也将优先开源出来给大家. 源码地址:https://github.com/S ...

  9. 止不住的裁员潮:看京东前员工吐槽——绩效打C还希望我好好干

    昨天,京东裁员消息被证实,京东将在2019年末位淘汰10%的副总裁级别以上的高管. 在互联网职场交流社区,一名自称京东的员工如此吐槽:办完离职了心情大好,自由放飞,明天入职新公司,你给新员工打C,还希 ...

  10. 新人入坑Redis必会的吐血总结

    新人入坑Redis必会的吐血总结 一.什么是Redis Redis是一个使用C语言开发的开源的高性能的key-value存储系统,我们可以把它近似理解为Java Map.简单来讲,Redis是一种NO ...