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 -------------------------------------- ...
随机推荐
- Lunix7 开放指定端口
systemctl unmask firewalld.service 此时可以正常启动Firewall了. 接下来顺便讲述一下Firewall的安装,及一些简单配置. 查看状态,看电脑上是否已经安 ...
- Jenkins持续集成构建
配置Sonar.Jenkins进行持续审查 http://go2live.cn/archives/38261.html Jenkins iOS 项目持续集成 http://go2live.cn/arc ...
- 基于weui的一个小插件
移动端项目当中大量的使用了weui,为了减少工作量,方便修改,自己写了个小插件,暂时只有toast和dialog部分,可能会更新actionSheet等其他部分 更新一个手机端预览的二维码,就直接放项 ...
- [SoapUI] 通过编程的方式设置当前的Environment
testRunner.testCase.testSuite.project.setActiveEnvironment("Live")
- loadlibrary 文档
http://www.pinvoke.net/default.aspx/kernel32.LoadLibrary LIBRARY ModelBank EXPORTS CND;GBlackScholes ...
- Python自然语言处理工具NLTK的安装FAQ
1 下载Python 首先去python的主页下载一个python版本http://www.python.org/,一路next下去,安装完毕即可 2 下载nltk包 下载地址:http://www. ...
- JSON Web Token(JWT)学习笔记
1.JWT 的Token 标准的Token由三个部分并以.(点号)连接方式组成,即 header.payload.signature,如下 eyJhbGciOiJIUzI1NiIsInR5cCI6Ik ...
- python 数据合并
1. 数据合并 前言 一.横向合并 1. 基本合并语句 2. 键值名不一样的合并 3. “两个数据列名字重复了”的合并 二.纵向堆叠 统计师的Python日记[第6天:数据合并] 前言 根据我的Pyt ...
- python str, list,tuple, dir
Python3 字符串 字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串. 创建字符串很简单,只要为变量分配一个值即可.例如: var1 = 'Hello ...
- mvc中图片的保存和显示
图片保存到网站根目录(例如 D:\www\Web)下 Web 应用程序根目录运算符用“~”表示.注意不是网站根目录(网站根目录是指针对域名计算的) 即便是网站部署在其他网站下(例如IIS中,在A站下( ...