【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), ...
随机推荐
- JS与JQ 获取页面元素值的方法和差异对比
获取浏览器高度和宽度 document.documentElement.clientWidth ==> 浏览器可见区域宽度 document.documentElement.clientHeig ...
- Injection of autowired dependencies failed;错误解决
代码自动生成的时候可能出现这个问题,反正我是找了半天才发现.serviceimp层不要写抽象类的声明abstract,这个删掉.
- C#中Json进行序列化时去掉值为null的节点
当我们用json文件为数据源时,并对json数据进行操作时可能会产生一些数值为null的节点生成,想要去掉null的节点需要一些操作 本文用一个简单的工具对json进行操作 工具:Newtonsoft ...
- Vue项目经验
Vue项目经验 setInterval路由跳转继续运行并没有及时进行销毁比如一些弹幕,走马灯文字,这类需要定时调用的,路由跳转之后,因为组件已经销毁了,但是setInterval还没有销毁,还在继续后 ...
- k8s学习目录
目录 K8S基础部分 基础部分 5 秒创建 k8s 集群[转] k8s 核心功能[转] k8s 重要概念[转] 部署 k8s Cluster(上)[转] 部署 k8s Cluster(下)[转] Ku ...
- json 将key值以字符串形式取出
int GetJsonCString(const Json::Value& value, char* str, int n){ if (!value.empty() && va ...
- Linux基础学习-MariaDB数据库管理系统
数据库管理系统 数据库是指按照某些特定结构来存储数据资料的数据仓库,数据库管理系统是一种能够对数据库中存放的数据进行建立.修改.删除.查找.维护等操作的软件程序. 初始化MariaDB服务 [root ...
- Linux文件权限基础(一)
Linux中每个文件或者目录对都有一组共9个基础权限位,没三位字符被分为一组,他们分别是属主权限位,用户组权限位,其他用户权限位. 示例: 权限位说明: r --read 可读权限 对应数字4 w - ...
- Web框架之Django_05 模型层了解(单表查询、多表查询、聚合查询、分组查询)
摘要: 单表查询 多表查询 聚合查询 分组查询 一.Django ORM 常用字段和参数: 常用字段:#AutoFieldint自增列,必须填入参数primary_key = True,当model中 ...
- Django 连接mysql数据库
首先在settings.py文件里将 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.pat ...