P3355 骑士共存问题 (最小割)
题意: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 骑士共存问题 (最小割)的更多相关文章
- 洛谷.3355.骑士共存问题(最小割ISAP)
题目链接 一个很暴力的想法:每个点拆点,向不能同时存在的连边 但是这样边太多了,而且会有很多重复.我不会说我还写了还没过样例 我们实际就是在做一个最大匹配.考虑原图,同在黄/红格里的骑士是互不攻击的, ...
- P3355 骑士共存问题
P3355 骑士共存问题 题目描述 在一个 n*n (n <= 200)个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n ...
- P3355 骑士共存问题 二分建图 + 当前弧优化dinic
P3355 骑士共存问题 题意: 也是一个棋盘,规则是“马”不能相互打到. 思路: 奇偶点分开,二分图建图,这道题要注意每个点可以跑八个方向,两边都可以跑,所以边 = 20 * n * n. 然后di ...
- 【Luogu】P3355骑士共存问题(最小割)
题目链接 像题面那样把棋盘染成红黄点.发现骑士迈一步能到达的点的颜色一定是跟他所在的格子的颜色不同的.于是(woc哪来的于是?这个性质有这么明显吗?)从源点向所有红点连边,从所有黄点向汇点连边,红点向 ...
- 洛谷P3355 骑士共存问题(最小割)
传送门 de了两个小时的bug愣是没发现错在哪里……没办法只好重打了一遍竟然1A……我有点想从这里跳下去了…… 和方格取数问题差不多,把格子按行数和列数之和的奇偶性分为黑的和白的,可以发现某种颜色一定 ...
- 洛谷P3355 骑士共存问题
题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置 ...
- P3355 骑士共存问题 网络流
骑士共存 题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最 ...
- 2018.08.02 洛谷P3355 骑士共存问题(最小割)
传送门 这题让我联想到一道叫做方格取数问题的题,如果想使摆的更多,就要使不能摆的更少,因此根据骑士的限制条件建图,求出至少有多少骑士不能摆,减一减就行了. 代码: #include<bits/s ...
- 洛谷 P3355 骑士共存问题【最小割】
同方格取数问题:https://www.cnblogs.com/lokiii/p/8430720.html 记得把障碍点去掉,不连边也不计入sum #include<iostream> # ...
随机推荐
- 【剑指 Offer】11.旋转数组的最小数字
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的 ...
- kubernets之服务的实现方式
一 服务如何通过kubernetes集群的组件来实现其功能 1.1 节点上的所有的服务相关的功能实现都是通过节点上面的kube-proxy来实现的,服务提供了一个或者多个服务IP以及端口对客户端开 ...
- java创建线程安全的类
如果一个对象想要被多个线程安全的并发访问,那么这个对象必须是或线程安全的或事实不可变的或由锁来保护的. 1.java监视器模式 大多数对象都是组合对象.当从头开始构建一个类,或者将多个非线程安全的类组 ...
- ABAP 面试问题和答案
What is an ABAP data dictionary?- ABAP 4 data dictionary describes the logical structures of the obj ...
- hive窗口函数/分析函数详细剖析
hive窗口函数/分析函数 在sql中有一类函数叫做聚合函数,例如sum().avg().max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的.但是有时 ...
- QTextEdit字符串的高亮显示问题
20130222 鬼猫猫 整理 http://www.cnblogs.com/muyr/ 解决方法的原始地址 http://www.qtcn.org/bbs/read.php?tid=20335 背景 ...
- linux静态库
库文件可以理解为别人写好的现成的代码,但是看不见源码,只提供程序入口.库又分为动态库和静态库,静态库是在编译的时候将库编译进可执行程序中,运行时不再依赖库文件,而动态库是在运行时加载,运行时需要依赖库 ...
- Python攻城——查看,生成幫助文檔
1. python在控制台中查看文檔 1 python -m pydoc 模塊名 2. pydoc生成HTML文檔 1 python -m pydoc -w 模塊名 1 python -m pydoc ...
- 树莓派zero 使用usb串口连接
使用minicom连接bash$ lsusbBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 001 Device 0 ...
- 将HDFS中指定文件的内容输出到终端。
1 import java.io.*; 2 import org.apache.hadoop.conf.Configuration; 3 import org.apache.hadoop.fs.*; ...