P4304 [TJOI2013]攻击装置 最小割
$ \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]攻击装置 最小割的更多相关文章
- 【BZOJ4808/3175】马/[Tjoi2013]攻击装置 最小割
[BZOJ4808]马 Description 众所周知,马后炮是中国象棋中很厉害的一招必杀技."马走日字".本来,如果在要去的方向有别的棋子挡住(俗称"蹩马腿" ...
- 洛谷P4304 [TJOI2013]攻击装置 题解
题目链接: https://www.luogu.org/problemnew/show/P4304 分析: 最大独立集 最大独立集=总点数-最大匹配数 独立集:点集,图中选一堆点,这堆点两两之间没有连 ...
- P4304 [TJOI2013]攻击装置
传送门 看到棋盘先黑白染色冷静一下 然后发现...攻击的时候同种颜色不会相互攻击 这样就是个网络流经典套路了,关于这个套路我以前好像写过几题,那边有解释一下:传送门 #include<iostr ...
- 洛咕 P4304 [TJOI2013]攻击装置
把坐标按照(x+y)%2染色可以发现这是个二分图 二分图最大独立集=点数-最大匹配 于是就是个算匹配的傻逼题了 // luogu-judger-enable-o2 #include<bits/s ...
- 洛谷P4304 TJOI2013 攻击装置 (二分图匹配)
题目大意:一个矩阵,一些点被拿掉,在棋盘上马走日,马之间不能落在同一点,求最多放几匹马. 采用对矩阵黑白染色,画个图可以发现:马可以走到的位置和他所处的位置颜色不同,将马和他可以走到的位置连边,最多可 ...
- 【洛谷】4304:[TJOI2013]攻击装置【最大点独立集】【二分图】2172: [国家集训队]部落战争【二分图/网络流】【最小路径覆盖】
P4304 [TJOI2013]攻击装置 题目描述 给定一个01矩阵,其中你可以在0的位置放置攻击装置. 每一个攻击装置(x,y)都可以按照“日”字攻击其周围的8个位置(x-1,y-2),(x-2,y ...
- bzoj4808: 马 & bzoj3175: [Tjoi2013]攻击装置 (黑白染色+最小割)
bzoj4808: 马 & bzoj3175: [Tjoi2013]攻击装置 题目:传送门 简要题意: 和n皇后问题差不多,但是这里是每个棋子走日子,而且有些格子不能放棋子.求最多能放多少个棋 ...
- BZOJ3175: [Tjoi2013]攻击装置
题解: 最大点独立集...好像水过头了... 不过发现我二分图好像忘完了!!! 代码: #include<cstdio> #include<cstdlib> #include& ...
- BZOJ 3175: [Tjoi2013]攻击装置( 匈牙利 )
黑白染成二分图, 然后不能同时选的就连边, 最大匹配数为m, t为不能放的数目, 则题目所求最大点独立集为 n*n-m-t -------------------------------------- ...
随机推荐
- jquery入门 动态调整div大小,使其宽度始终为浏览器宽度
有时候我们需要设置宽度为整个浏览器宽度的div,当然我们可以使用相对布局的方式做到这一点,不过我们也可以用jquery来实现. <!doctype html> <html> & ...
- springboot用于web开发
1.使用SpringBoot:1)创建SpringBoot应用,选中我们需要的模块:2)SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来3)自己编写业务代码 ...
- django项目搭建及Session使用
django+session+中间件 一.使用命令行创建django项目 在指定路径下创建django项目 django-admin startproject djangocommon 在项目目录 ...
- Python OCR提取普通数字图形验证中的数字
截取图形验证码: # -*- coding: UTF-8 -*- ''' Created on 2016年7月4日 @author: xuxianglin ''' import os import t ...
- 浅谈c/c++中的指针问题
首先给出几种指针类型来作出区分,不看后面的解析如果可以自己分辨正确那么就算对指针有一个很好的掌握了,就没有必要再去看后面的解析,如果不能完全区分,那么就有必要仔细看看后面解析. 1 Char * p ...
- loadrunner12-错误 -26366: 找不到 web_reg_find 的“Text=19728.00”
转:检查点(web_reg_find函数详解) LR检查点 设置检查点的目的不只是为了验证我们的脚本没有错误,而更重要的是一个规范问题,如何使得测试结果更具有说服力,因此建议所有的测试脚本中都添加检查 ...
- code4511 信息传递
寻找最小环 #include <cstdio> #include <cstring> #include <iostream> using namespace std ...
- 修改字段名change
ALTER TABLE tc_activity_miaosha_item CHANGE `batch_id` `movie_batch_id` INT () NOT NULL DEFAULT ' CO ...
- SQL序列键
当需要更新表中的数据或像表中插入数据时,在很多情况下需要产生唯一的整数序列键 一:更新列的值为唯一值 原数据如下图: 可以定义一个CTE,返回orerid列的值以及row_number()的计算结果. ...
- osg反走样
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits-& ...