$ \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. ios加载本地html

    UIWebView加载工程本地网页与本地图片 - (void)viewDidLoad { [super viewDidLoad]; NSString *filePath = [[NSBundle ma ...

  2. Navicat修改查询保存路径

    mysql使用navicat查询时有时候会有很多sql语句, ctrl+s时自动保存在C:\Users\Administrator\Documents\Navicat\MySQL\servers\lo ...

  3. code1091 传染病控制

    1.读入图,边是双向的 2.递归建树,同时确定每一层的节点 3.dfs按层搜索,先把这一层所有被传染的(die[pa[k]]=true的)的die置为true 然后循环,每次把一个die为true的变 ...

  4. 修复jqgrid setgridparam postdata 的多次查询条件累加

    //根据elements查询出的参数个数的不同,而传递不同个数的查询参数 start var elements = node.attributes.text.split(","); ...

  5. 白盒测试实践--Day3 12/19/2017

    累计完成任务情况: 阶段内容 参与人 完成静态代码检查结果报告 小靳 完成JUnit脚本编写 小黄 完成CheckStyle检查 小靳 完成代码评审会议纪要和结果报告 小熊.小梁及其他 完成白盒测试用 ...

  6. sqlserver 2005范例代码查询辞典文摘

    第1章 select 1.显示指定想要获取的列要比使用select *更好 2.where not m.MemberCode = 1000 3.select * into aaa from Membe ...

  7. QtCreator下QML翻译

    首先打开.pro工程文件,在文件中添加文本段:TRANSLATIONS = testTranslate_zh.ts 在pro右键,单击再次弹出命令提示,如图 在命令行中,输入lupdate testT ...

  8. java/rabbitmp发布订阅示例(转)

    原文:http://www.cnblogs.com/tinmh/p/6134875.html 发布/订阅模式即生产者将消息发送给多个消费者. 下面介绍几个在发布/订阅模式中的关键概念-- 1. Exc ...

  9. WordPaster-Joomla_3.4.7-tinymce 4.1.7示例发布

    资源下载:Joomla 3x,   1.1.1. 1.添加wordpaster文件夹 /media/   1.1.2. 2.添加插件文件夹 路径:media/editors/tinymce/plugi ...

  10. 编写高质量代码改善C#程序的157个建议——建议139:事件处理器命名采用组合方式

    建议139:事件处理器命名采用组合方式 所谓事件处理器,就是实际被委托执行的那个方法.查看如下代码: public MainWindow() { InitializeComponent(); Butt ...