题意: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. XEE - Pikachu

    概述 XXE -"xml external entity injection"既"xml外部实体注入漏洞".概括一下就是"攻击者通过向服务器注入指定的 ...

  2. 1 分钟上手,在容器中运行 Visual Studio Code

    https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers 这个插件允许我们在容器中运 ...

  3. git创建分支并关联远程分支

    1.新建本地分支: 如图,再输入你的分支名字,然后选择从哪个远程分支拉代码,如选择master 至此本地分支创建完成. 2.关联远程分支: (1).先输入git branch -vv,看看分支与远程分 ...

  4. 05--Docker对DockerFile解析

    一.是什么: 1.1 DockerFile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本 1.2 构建步骤: 1.2.1 编写Dockerfile文件 1.2.2 docker ...

  5. Windows下nginx设置开机自启动

    第一步:下载 WinSW https://github.com/winsw/winsw/releases/download/v2.10.3/WinSW.NET4.exe 64位系统 https://g ...

  6. vue-cli3x4x修改本地端口port

    一.推荐方法 "scripts": { "serve": "vue-cli-service serve --port 3000", &quo ...

  7. k8s之共享存储概述以及演示

    共享存储机制 k8s对有状态的容器应用或者需要对数据进行持久化的应用,在之前的篇章说过,可以将容器内的目录挂载到宿主机的容器目录或者emptyDir临时存储卷. 另外,k8s还开放了两个资源,分别是P ...

  8. Markdown里常用的HTML元素

    转义:\ 换行:<br/> 红色文字:<font color=#FF0000>字体改成红色了</font> A标签 新窗口:<a href="xxx ...

  9. git commit前检测husky与pre-commit 提交钩子

    git commit前检测husky与pre-commit git commit前检测husky与pre-commit - 简书 https://www.jianshu.com/p/f0d31f92b ...

  10. python 11 模块

    模块 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较 ...