$ \color{#0066ff}{ 题目描述 }$

给定一个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-1条路连接它们,且它们两两都可达。每个工厂都有一个产量值和一个污染值。现在工厂要进行规划,拆除其中的M个工厂,使得剩下的工厂依然连成一片且 总产量/总污染 的值最大。

\(\color{#0066ff}{输入格式}\)

第一行一个整数N,表示矩阵大小为N*N。

接下来N行每一行一个长度N的01串,表示矩阵。

\(\color{#0066ff}{输出格式}\)

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

\(\color{#0066ff}{输入样例}\)

3
010
000
100

\(\color{#0066ff}{输出样例}\)

4

\(\color{#0066ff}{数据范围与提示}\)

30%数据N<=50

100%数据 N<=200

\(\color{#0066ff}{题解}\)

发现两个互相影响的块的奇偶性不同, 于是黑白染色跑最小割

#include<bits/stdc++.h>
#define LL long long
LL read() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
template<class T> bool chkmax(T &a, const T &b) { return a < b? a = b, 1 : 0; }
template<class T> bool chkmin(T &a, const T &b) { return b < a? a = b, 1 : 0; }
const int inf = 0x7fffffff;
const int maxn = 1e5 + 10;
struct node {
int to, can;
node *nxt, *rev;
node(int to = 0, int can = 0, node *nxt = NULL): to(to), can(can), nxt(nxt) { rev = NULL; }
};
node *head[maxn], *cur[maxn];
int dep[maxn], n, s, t, mp[400][400];
int rx[] = {-2, -2, -1, -1, 1, 1, 2, 2};
int ry[] = {-1, 1, -2, 2, -2, 2, -1, 1};
bool bfs() {
for(int i = s; i <= t; i++) dep[i] = 0, cur[i] = head[i];
std::queue<int> q;
q.push(s); dep[s] = 1;
while(!q.empty()) {
int tp = q.front(); q.pop();
for(node *i = head[tp]; i; i = i->nxt)
if(!dep[i->to] && i->can)
dep[i->to] = dep[tp] + 1, q.push(i->to);
}
return dep[t];
}
int dfs(int x, int change) {
if(x == t || !change) return change;
int flow = 0, ls;
for(node *&i = cur[x]; i; i = i->nxt)
if(dep[i->to] == dep[x] + 1 && (ls = dfs(i->to, std::min(change, i->can)))) {
change -= ls;
flow += ls;
i->can -= ls;
i->rev->can += ls;
if(!change) break;
}
return flow;
}
int dinic() {
int flow = 0;
while(bfs()) flow += dfs(s, inf);
return flow;
}
int id(int x, int y) { return (x - 1) * n + y; }
void add(int from, int to, int can) { head[from] = new node(to, can, head[from]); }
void link(int from, int to, int can) {
add(from, to, can), add(to, from, 0);
head[from]->rev = head[to]; head[to]->rev = head[from];
}
int main() {
n = read();
int tot = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
scanf("%1d", &mp[i][j]);
tot += mp[i][j];
}
tot = n * n - tot;
s = 0, t = n * n + 1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
if(mp[i][j]) continue;
if((i + j) & 1) link(id(i, j), t, 1);
else link(s, id(i, j), 1
);
if((i + j) & 1) continue;
for(int k = 0; k < 8; k++) {
int xx = i + rx[k];
int yy = j + ry[k];
if(xx >= 1 && xx <= n && yy >= 1 && yy <= n && !mp[xx][yy]) link(id(i, j), id(xx, yy), inf);
}
}
printf("%d\n", tot - dinic());
return 0;
}

P4304 [TJOI2013]攻击装置 最小割的更多相关文章

  1. 【BZOJ4808/3175】马/[Tjoi2013]攻击装置 最小割

    [BZOJ4808]马 Description 众所周知,马后炮是中国象棋中很厉害的一招必杀技."马走日字".本来,如果在要去的方向有别的棋子挡住(俗称"蹩马腿" ...

  2. 洛谷P4304 [TJOI2013]攻击装置 题解

    题目链接: https://www.luogu.org/problemnew/show/P4304 分析: 最大独立集 最大独立集=总点数-最大匹配数 独立集:点集,图中选一堆点,这堆点两两之间没有连 ...

  3. P4304 [TJOI2013]攻击装置

    传送门 看到棋盘先黑白染色冷静一下 然后发现...攻击的时候同种颜色不会相互攻击 这样就是个网络流经典套路了,关于这个套路我以前好像写过几题,那边有解释一下:传送门 #include<iostr ...

  4. 洛咕 P4304 [TJOI2013]攻击装置

    把坐标按照(x+y)%2染色可以发现这是个二分图 二分图最大独立集=点数-最大匹配 于是就是个算匹配的傻逼题了 // luogu-judger-enable-o2 #include<bits/s ...

  5. 洛谷P4304 TJOI2013 攻击装置 (二分图匹配)

    题目大意:一个矩阵,一些点被拿掉,在棋盘上马走日,马之间不能落在同一点,求最多放几匹马. 采用对矩阵黑白染色,画个图可以发现:马可以走到的位置和他所处的位置颜色不同,将马和他可以走到的位置连边,最多可 ...

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

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

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

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

  8. BZOJ3175: [Tjoi2013]攻击装置

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

  9. BZOJ 3175: [Tjoi2013]攻击装置( 匈牙利 )

    黑白染成二分图, 然后不能同时选的就连边, 最大匹配数为m, t为不能放的数目, 则题目所求最大点独立集为 n*n-m-t -------------------------------------- ...

随机推荐

  1. 由浅到深理解ROS(5)- launch启动文件的理解与编写

    ROS提供了一个同时启动节点管理器(master)和多个节点的途径,即使用启动文件(launch file).事实上,在ROS功能包中,启动文件的使用是非常普遍的.任何包含两个或两个以上节点的系统都可 ...

  2. Openssl s_server命令

    一.简介 s_server是openssl提供的一个SSL服务程序.使用此程序前,需要生成各种证书.本命令可以用来测试ssl客户端,比如各种浏览器的https协议支持 二.语法 openssl s_s ...

  3. [Fiddler]如何让Fiddler可以抓取https的请求

    Fiddler通过在本机开启了一个http的代理服务器来进行http请求和响应转发,默认情况下,并不能抓取https的请求.下面小编就来介绍下,如何用fiddler来抓取https的请求. 1.打开F ...

  4. SetDns.bat 2014-03-28 20:00:19

    此BAT文件,可以帮助便捷切换dns设置,Win7系统需使用管理员身份运行. @echo off echo 设置为GoogleDNS(1)/dhcp(2)/OpenDNS(3) set /p sel= ...

  5. 大前端涉猎之前后端交互总结1: 软件架构与PHP搭建

    1 软件架构与PHP搭建 1.1 HTTP服务器(web服务器) 即( web服务器 )网站服务器,主要提供文档(文本.图片.视频.音频)web浏览服务,一般安装Apache.Nginx服务器软件. ...

  6. 引用数据类型(类)和ArrayList

    引用数据类型(类) 类的类型为两种: 第一种,Java为我们提供好的类,如Scanner类,Scanner类等,这些已存在的类中包含了很多的方法与属性,可供我们使用. 第二种,我们自己创建的类,按照类 ...

  7. Python之模块二

    10>常用模块: 1>os模块: os.getcwd():获取当前工作目录,即当前python脚本工作的目录路径: os.chdir("dirname"):改变当前脚本 ...

  8. Python相关基础

    1>变量: 2>条件判断与缩进: sex = raw_input("Please input your gender:") if sex == "girl&q ...

  9. jeecms栏目模型和内容模型的使用以及对应前台的标签中的属性名

    第一步:模型管理-添加模型: 栏目模板前缀设定方案下的channel目录下的ch_menu.html作为浏览栏目的模板页.对应访问网址:项目名/栏目名(一级或者二级栏目如news或者gnxw)/ind ...

  10. 5、Semantic-UI之基础按钮样式

    5.1 基础按钮样式   在Semantic-UI中定义了很多的按钮样式,可以通过class="ui button"来指定,也可以在class中指定颜色. 示例:定义基础按钮样式 ...