【Codevs1922】骑士共存问题(最小割,二分图最大独立集转最大匹配)
题意:
在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘
上某些方格设置了障碍,骑士不得进入。

对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击。
n<=200,m<=n^2
思路:经典的二分图最大独立集,采用黑白点染色的思想。
如果按照相邻点黑白不同染色,可以发现每次跳到的点必定与现在所在点不同色,二分图最大匹配即可。
每切断一条黑白点之间的边就是少放了一个骑士,用最小割算出最少要切断几条边,总数减去有障碍的再减切断的边数就是最大匹配数,最大独立集又可以转化为最大匹配数。
这里用最小割来解决,因为不能允许任何黑白点之间的任何一条边有流量,符合最小割的思想。
const dx:array[..]of longint=(-,-,-,-,,,,);
dy:array[..]of longint=(-,,-,,-,,-,);
var head,vet,next,len,fan,gap,dis:array[..]of longint;
b,num,a:array[..,..]of longint;
n,m,i,tot,x,y,k,j,source,src,s:longint; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; function dfs(u,aug:longint):longint;
var e,v,val,flow,t:longint;
begin
if u=src then exit(aug);
flow:=; val:=s-;
e:=head[u];
while e<> do
begin
v:=vet[e];
if len[e]> then
begin
if dis[u]=dis[v]+ then
begin
t:=dfs(v,min(len[e],aug-flow));
len[e]:=len[e]-t;
len[fan[e]]:=len[fan[e]]+t;
flow:=flow+t;
if dis[source]>=s then exit(flow);
if aug=flow then break;
end;
val:=min(val,dis[v]);
end;
e:=next[e];
end;
if flow= then
begin
dec(gap[dis[u]]);
if gap[dis[u]]= then dis[source]:=s;
dis[u]:=val+;
inc(gap[dis[u]]);
end;
exit(flow);
end; function maxflow:longint;
var ans:longint;
begin
fillchar(gap,sizeof(gap),);
fillchar(dis,sizeof(dis),);
gap[]:=s; ans:=;
while dis[source]<s do ans:=ans+dfs(source,maxlongint);
exit(ans);
end; begin
assign(input,'codevs1922.in'); reset(input);
assign(output,'codevs1922.out'); rewrite(output);
read(n,m);
for i:= to n do
for j:= to n do
begin
inc(s); a[i,j]:=(i+j+) mod ; num[i,j]:=s;
end;
for i:= to m do
begin
read(x,y);
b[x,y]:=;
end;
s:=n*n+;
for i:= to n do
for j:= to n do
if (a[i,j]=)and(b[i,j]=) then
begin
for k:= to do
begin
x:=i+dx[k]; y:=j+dy[k];
if (x>)and(x<=n)and(y>)and(y<=n)and(b[x,y]=) then
begin
fan[tot+]:=tot+;
fan[tot+]:=tot+;
add(num[i,j],num[x,y],);
add(num[x,y],num[i,j],);
end;
end;
end;
source:=; src:=;
for i:= to n do
for j:= to n do
if a[i,j]= then
begin
fan[tot+]:=tot+;
fan[tot+]:=tot+;
add(source,num[i,j],);
add(num[i,j],source,);
end
else if b[i,j]= then
begin
fan[tot+]:=tot+;
fan[tot+]:=tot+;
add(num[i,j],src,);
add(src,num[i,j],);
end;
writeln(n*n-m-maxflow);
close(input);
close(output);
end.
【Codevs1922】骑士共存问题(最小割,二分图最大独立集转最大匹配)的更多相关文章
- 【最小割/二分图最大独立集】【网络流24题】【P2774】 方格取数问题
Description 给定一个 \(n~\times~m\) 的矩阵,每个位置有一个正整数,选择一些互不相邻的数,最大化权值和 Limitation \(1~\leq~n,~m~\leq~100\) ...
- 洛谷.3355.骑士共存问题(最小割ISAP)
题目链接 一个很暴力的想法:每个点拆点,向不能同时存在的连边 但是这样边太多了,而且会有很多重复.我不会说我还写了还没过样例 我们实际就是在做一个最大匹配.考虑原图,同在黄/红格里的骑士是互不攻击的, ...
- P3355 骑士共存问题 (最小割)
题意:nxn的棋盘 有m个坏点 求能在棋盘上放多少个马不会互相攻击 题解:这个题仔细想想居然和方格取数是一样的!!! 每个马他能攻击到的地方的坐标 (x+y)奇偶性不一样 于是就黑白染色 s-> ...
- Codevs1922 骑士共存问题
1922 骑士共存问题 题目描述 Description 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的n*n个方格的国 ...
- POJ3308 Paratroopers(最小割/二分图最小点权覆盖)
把入侵者看作边,每一行每一列都是点,选取某一行某一列都有费用,这样问题就是选总权最小的点集覆盖所有边,就是最小点权覆盖. 此外,题目的总花费是所有费用的乘积,这时有个技巧,就是取对数,把乘法变为加法运 ...
- BZOJ 1934 Vote 善意的投票(最小割+二分图)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1934 题目大意: 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题 ...
- 【wikioi】1922 骑士共存问题(网络流/二分图匹配)
用匈牙利tle啊喂?和网络流不都是n^3的吗(匈牙利O(nm), isap O(n^2m) 但是isap实际复杂度很优的(二分图匹配中,dinic是O(sqrt(V)*E),不知道isap是不是一样. ...
- BZOJ 3774 最优选择 (最小割+二分图)
题面传送门 题目大意:给你一个网格图,每个格子都有$a_{ij}$的代价和$b_{ij}$的回报,对于格子$ij$,想获得$b_{ij}$的回报,要么付出$a_{ij}$的代价,要么$ij$周围四联通 ...
- BZOJ3175:[TJOI2013]攻击装置(二分图最大独立集)
Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y-1),(x+1,y-2), ...
随机推荐
- myeclipse报错MA
以下问题萌新问了我很多次了,无奈写个随笔.之后问的我都在这个随笔里补充. 断电/自动关机导致的问题: Could not open the editor: the file does not exis ...
- 多源最短路径 – Floyd-Warshall Algorithm
介绍: 是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包. Floyd-Warshall算法的时间复杂度是O(N3) ...
- scss引入的问题
导入.sass或.scss文件 css有一个不太常用的特性,即@import 导入功能,它允许在一个css文件中导入其他css文件.然而,结果是只有执行到@import 规则时,浏览器才会去下载其他c ...
- 快学UiAutomator各种框架介绍
Monkey 编写语言:命令行 运行环境:使用adb连接PC运行测试对象:Android平台自动化测试的一种手段,通过Monkey程序模拟用户触摸屏幕.滑动Trackball.按键等操作来对设备上的程 ...
- Base64编码密钥时关于换行的几个问题。
在windows下一个javaweb应用,需要用http传递公钥pk.一般是String pk = BASE64ENCODER.encode(pkBytes);base64编码时,每76个字母就要换行 ...
- ios之NSURLRequest&NSURLConnection
网络编程中一般都是经过 请求--->连接--->响应 (request --> connection --> response)这个过程. 一般的步骤是这样的: ...
- 【IDE_PyCharm】PyCharm中配置当鼠标悬停时快速提示方法参数
方法一:通过在settings里面设置当鼠标至于方法之上时给出快速提示 方法二:按住Ctrl键,光标放在任意变量或方法上都会弹出该变量或方法的详细信息,点击鼠标还能跳转到变量或方法的定义处
- (转)Duplicate Symbol链接错的原因总结和解决方法
duplicate symbol是一种常见的链接错误,不像编译错误那样可以直接定位到问题的所在.但是经过一段时间的总结,发现这种错误总是有一些规律可以找的.例如,我们有如下的最简单的两个类代码: // ...
- PAT Basic 1013
1013 数素数 令P~i~表示第i个素数.现任给两个正整数M <= N <= 10^4^,请输出P~M~到P~N~的所有素数. 输入格式: 输入在一行中给出M和N,其间以空格分隔. 输出 ...
- C#上位机开发(二)—— Hello,World
上一篇大致了解了一下单片机实际项目开发中上位机开发部分的内容以及VS下载与安装,按照编程惯例,接下来就是“Hello,World!” 1.新建C#项目工程 首先选择新建Windows窗体应用(.NET ...