BZOJ3175[Tjoi2013]攻击装置——二分图最大独立集
题目描述
给定一个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)
求在装置互不攻击的情况下,最多可以放置多少个装置。
输入
输出
样例输入
010
000
100
样例输出
提示
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]攻击装置——二分图最大独立集的更多相关文章
- BZOJ3175:[TJOI2013]攻击装置(二分图最大独立集)
Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y-1),(x+1,y-2), ...
- bzoj4808: 马 & bzoj3175: [Tjoi2013]攻击装置 (黑白染色+最小割)
bzoj4808: 马 & bzoj3175: [Tjoi2013]攻击装置 题目:传送门 简要题意: 和n皇后问题差不多,但是这里是每个棋子走日子,而且有些格子不能放棋子.求最多能放多少个棋 ...
- BZOJ3175: [Tjoi2013]攻击装置
题解: 最大点独立集...好像水过头了... 不过发现我二分图好像忘完了!!! 代码: #include<cstdio> #include<cstdlib> #include& ...
- 【BZOJ 3175】 3175: [Tjoi2013]攻击装置(二分图匹配)
3175: [Tjoi2013]攻击装置 Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2) ...
- BZOJ3175 Tjoi2013 攻击装置(二分图匹配)
传送门 Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照"日"字攻击其周围的 8个位置(x-1,y-2),(x-2,y ...
- [TJOI2013] 攻击装置 - 二分图匹配
给定 \(N \times N\) 棋盘,某些格子是障碍,问可以放置的互不侵犯的马的个数 黑白染色后建立二分图,求最大独立集 = 总点数 - 最大匹配数 注意把反边也连上会WA掉(脑抽一发血) #in ...
- bzoj3175: [Tjoi2013]攻击装置&&4808: 马
终于知道为啥网络流这么受欢迎了. 其实就是构个图模板一下的事儿,比较好打是吧. 然后这题网络流黑白染色(其实感觉上匈牙利更加直接好想啊,但是实际上黑白染色给人感觉就是二分图) st连白而ed连黑,流量 ...
- BZOJ_3175_[Tjoi2013]攻击装置_二分图匹配
BZOJ_3175_[Tjoi2013]攻击装置_二分图匹配Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置 ...
- 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】
P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...
随机推荐
- P4208 [JSOI2008]最小生成树计数
现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)输出方案数对31011 ...
- ssl协议
在互联网安全通信方式上,目前用的最多的就是https配合ssl和数字证书来保证传输和认证安全了.本文追本溯源围绕这个模式谈一谈. 1.首先解释一下上面的几个名词: https:在http(超文本传输协 ...
- .NET Core 3.0 跟踪
Preview1: https://blogs.msdn.microsoft.com/dotnet/2018/12/04/announcing-net-core-3-preview-1-and-ope ...
- java线程池和中断总结
目录 java线程池和中断总结 一. 线程池的使用 二. java中断机制 中断的处理 三. 线程间通信机制总结 java线程池和中断总结 本系列文是对自己学习多线程和平时使用过程中的知识梳理,不适合 ...
- odoo 订餐系统之消息提醒
打算入手odoo开发新的系统,先研究下开发的过程是如何的.案例模仿自带的订餐系统,此系统模块不多,但很典型,可以达到联系的目的.先记录下订餐系统消息提醒的开发过程. 1.添加自己的addons目录my ...
- 【Java并发.1】简介
继上一本<深入理解Java虚拟机>之后,学习计划里的另一本书<Java并发编程实战>现在开始学习,并记录学习笔记. 第一章主要内容是介绍 并发 的简介.发展.特点. 编写正确的 ...
- Jmeter(三十五)_精确实现网页爬虫
Jmeter实现了一个网站文章的爬虫,可以把所有文章分类保存到本地文件中,并以文章标题命名 它原理就是对网页提交一个请求,然后把返回的所有值提取出来,利用ForEach控制器去实现遍历.下面来介绍一下 ...
- Docker容器学习梳理 - 私有仓库Registry使用
但有时候使用Docker Hub这样的公共仓库可能不方便,这种情况下用户可以使用registry创建一个本地仓库供私人使用,这点跟Maven的管理类似.使用私有仓库有许多优点: 1)节省网络带宽,针对 ...
- 运维中的日志切割操作梳理(Logrotate/python/shell脚本实现)
对于Linux系统安全来说,日志文件是极其重要的工具.不知为何,我发现很多运维同学的服务器上都运行着一些诸如每天切分Nginx日志之类的CRON脚本,大家似乎遗忘了Logrotate,争相发明自己的轮 ...
- BAT大厂面试流程剖析
在当今互联网中,虽然互联网行业从业者众多,不断崛起的互联网公司也会很多,但如BAT等大厂,仍然是很多同学想要进入的企业.那么本篇文章将会为大家很直白的讲解大厂的面试流程以及侧重点. 首先闲聊一下,为什 ...