题意:nxn的棋盘 有m个坏点 求能在棋盘上放多少个马不会互相攻击

题解:这个题仔细想想居然和方格取数是一样的!!!

   每个马他能攻击到的地方的坐标 (x+y)奇偶性不一样 于是就黑白染色

   s->黑 白->t

   按条件连黑->白 跑最小割 = 最大流

   感性理解一下 就是先把所有的点都放上 得到最大的收益

   然后删掉一些点使得合法 删掉一个黑点 减去黑点的收益 和黑点相连的白点受到的束缚就减少了

   如果s和t点能联通的话 表示还有黑点和白点连通 问题就转化为了最小割

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int n, m, s, t, cnt, maxflow;
int broke[205][205]; struct node {
int to, nex, val;
}E[400005];
int head[40005];
int cur[40005];
int dx[] = {-1, -1, 1, 1, -2, -2, 2, 2};
int dy[] = {2, -2, 2, -2, 1, -1, 1, -1}; void addedge(int x, int y, int va) {
E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va;
E[++cnt].to = x; E[cnt].nex = head[y]; head[y] = cnt; E[cnt].val = 0;
} int dep[40005];
int inque[40005];
bool bfs() {
for(int i = 0; i <= t; i++) dep[i] = INF, inque[i] = 0, cur[i] = head[i];
queue<int> que;
dep[s] = 0; inque[s] = 1;
que.push(s); while(!que.empty()) {
int u = que.front();
que.pop();
inque[u] = 0; for(int i = head[u]; i; i = E[i].nex) {
int v = E[i].to;
if(E[i].val > 0 && dep[v] > dep[u] + 1) {
dep[v] = dep[u] + 1;
if(!inque[v]) {
que.push(v);
inque[v] = 1;
}
}
}
}
if(dep[t] != INF) return true;
return false;
} int vis;
int dfs(int x, int flow) {
if(x == t) {
vis = 1;
maxflow += flow;
return flow;
} int used = 0;
int rflow = 0;
for(int i = cur[x]; i; i = E[i].nex) {
cur[x] = i;
int v = E[i].to;
if(E[i].val > 0 && dep[v] == dep[x] + 1) {
if(rflow = dfs(v, min(flow - used, E[i].val))) {
used += rflow;
E[i].val -= rflow;
E[i ^ 1].val += rflow;
if(used == flow) break;
}
}
}
return used;
} void dinic() {
maxflow = 0;
while(bfs()) {
vis = 1;
while(vis) {
vis = 0;
dfs(s, INF);
}
}
} int id(int x, int y) {
return (x - 1) * n + y;
} bool check(int x, int y) {
if(x >= 1 && x <= n && y >= 1 && y <= n) return true;
return false;
} int main() {
cnt = 1;
scanf("%d%d", &n, &m);
s = 0;
t = n * n + 1; for(int i = 1; i <= m; i++) {
int x, y; scanf("%d%d", &x, &y);
broke[x][y] = 1;
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
int ii = id(i, j);
if(broke[i][j]) continue; if((i + j) % 2 != 1) {
addedge(s, ii, 1);
for(int k = 0; k < 8; k++) {
int ax = i + dx[k];
int ay = j + dy[k];
if(check(ax, ay) && !broke[ax][ay]) addedge(ii, id(ax, ay), INF);
}
} else addedge(ii, t, 1);
}
}
dinic();
printf("%d\n", n * n - m - maxflow);
return 0;
}

P3355 骑士共存问题 (最小割)的更多相关文章

  1. 洛谷.3355.骑士共存问题(最小割ISAP)

    题目链接 一个很暴力的想法:每个点拆点,向不能同时存在的连边 但是这样边太多了,而且会有很多重复.我不会说我还写了还没过样例 我们实际就是在做一个最大匹配.考虑原图,同在黄/红格里的骑士是互不攻击的, ...

  2. P3355 骑士共存问题

    P3355 骑士共存问题 题目描述 在一个 n*n (n <= 200)个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n ...

  3. P3355 骑士共存问题 二分建图 + 当前弧优化dinic

    P3355 骑士共存问题 题意: 也是一个棋盘,规则是“马”不能相互打到. 思路: 奇偶点分开,二分图建图,这道题要注意每个点可以跑八个方向,两边都可以跑,所以边 = 20 * n * n. 然后di ...

  4. 【Luogu】P3355骑士共存问题(最小割)

    题目链接 像题面那样把棋盘染成红黄点.发现骑士迈一步能到达的点的颜色一定是跟他所在的格子的颜色不同的.于是(woc哪来的于是?这个性质有这么明显吗?)从源点向所有红点连边,从所有黄点向汇点连边,红点向 ...

  5. 洛谷P3355 骑士共存问题(最小割)

    传送门 de了两个小时的bug愣是没发现错在哪里……没办法只好重打了一遍竟然1A……我有点想从这里跳下去了…… 和方格取数问题差不多,把格子按行数和列数之和的奇偶性分为黑的和白的,可以发现某种颜色一定 ...

  6. 洛谷P3355 骑士共存问题

    题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置 ...

  7. P3355 骑士共存问题 网络流

    骑士共存 题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最 ...

  8. 2018.08.02 洛谷P3355 骑士共存问题(最小割)

    传送门 这题让我联想到一道叫做方格取数问题的题,如果想使摆的更多,就要使不能摆的更少,因此根据骑士的限制条件建图,求出至少有多少骑士不能摆,减一减就行了. 代码: #include<bits/s ...

  9. 洛谷 P3355 骑士共存问题【最小割】

    同方格取数问题:https://www.cnblogs.com/lokiii/p/8430720.html 记得把障碍点去掉,不连边也不计入sum #include<iostream> # ...

随机推荐

  1. Spark学习进度10-DS&DF基础操作

    有类型操作 flatMap 通过 flatMap 可以将一条数据转为一个数组, 后再展开这个数组放入 Dataset val ds1=Seq("hello spark"," ...

  2. 关于vuex的数据不直接给data而要通过computed

    # 为什么vuex的数据不直接给data而要通过computed计算 ## 疑惑 其实一直以来使用vue的状态管理vuex都有一个疑惑,文档中介绍,vue的状态数据`$store.state.xx`的 ...

  3. Flutter 布局类组件:层叠布局(Stack和Positioned)

    前言 层叠布局,即子组件可以根据距父容器四个角的位置来确定自身的位置.绝对定位运行子组件堆叠起来,即按照代码中声明的顺序. Flutter中使用Stack和Positioned这两个组件来配合实现绝对 ...

  4. HAProxy-1.8.20 根据后缀名转发到后端服务器

    global maxconn 100000 chroot /data/soft/haproxy stats socket /var/lib/haproxy/haproxy.sock mode 600 ...

  5. 基础练习(上) - 蓝桥杯(Python实现)

    闰年判断: 题目: 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个年份,判断这一年是不是闰年. 当以下情况之一满足时,这一年是闰年: 1. 年份是4的倍数而不是100的倍数 ...

  6. 关于postgresql中numeric和decimal的精度和标度问题

    精度即数的有效数字个数 2.5的有效数字个数是2,但是053.2的有效数字个数是3 标度是小数点的位数 例如numeric(2,1),即这个数必须是两位,并且小数后面最多有一位,多出来的小数会被四舍五 ...

  7. 鸿蒙的远程交互组件应用及微信小程序的远程交互组件应用

    注:鸿蒙的远程交互组件应用相对复杂 ,访问网络时,首先要配置网络权限,华为官方文档有问题,在此引用我老师配置的模板,见附件 过程:1.导入鸿蒙的网络请求模块fetch 2.发起对服务器的请求(在这过程 ...

  8. CTS相关的几个表

    TMSALOG/TMSALOGAR :STMS传输日志表 TMSCNFS:传输组 TMSCDOM:传输域 TMSCDES:传输目的地 TMSBUFTXT:传输请求的短文本和用户 TMSCSYS:tms ...

  9. 安装JDK与卸载JDK教程

    卸载JDK 删除JDK的安装目录,也就是删除了主程序(通过环境变量可以找到) 删除java_home的环境变量 删除环境变量path中与java_home相关的 通过DOS命令cmd来检验是否卸载成功 ...

  10. JavaScript中的Promise【期约】[未完成]

    JavaScript中的Promise[期约] 期约主要有两大用途 首先是抽象地表示一个异步操作.期约的状态代表期约是否完成. 比如,假设期约要向服务器发送一个 HTTP 请求.请求返回 200~29 ...