bzoj1443
首先要思考的问题肯定是,什么点可以是ans,
不难想到对图黑白染色,假如一个棋子不管怎么走,都只能走到和它同色的点上时,这就是一个ans
再考虑,每次棋子的移动都是黑白相间的
再考虑,黑白染色是可以构成一个二分图的
不难想到,二分图上的增广路。
于是第一问就很好解决,我们构建二分图做最大匹配,
如果所有的黑点和白点都匹配了,那么一定不存在,否则一定存在。
为什么呢?
我们知道,如果这个匹配是二分图的最大匹配,那么图中一定不存在增广路;
而增广路是指从非匹配边最终走到非匹配边(非匹配边比匹配边数多1);
假存在一个未被匹配的点,那么小AA将棋子放在这个点上,
那么下一步小YY要么没法走,要么只能走到一个匹配过的点上,走了一条非匹配边。
那么小AA这要走这个点的匹配边,那下一步小YY要么没法走,要么只能走一条非匹配边
这样下去,我们知道是不存在增广路的,那么最后一步一定走的是匹配边——即小AA走最后一步
所以,只要最大匹配中存在未匹配点,那么这个点就是答案之一;
那答案是不是只有这些点呢?
不是,因为最大匹配不止一种,可以有其他点在最大匹配中未被匹配;
考虑到这样一种情况,我们从一个未匹配点k出发,如果走到了一个被匹配点i,记i原来匹配的点为j
如果我们仅仅改变让i和k匹配,而不和j匹配,那么这样并没有改变最大匹配的数目,而又找到了一个新的点他可以不被匹配
那么这个点显然也是ans
所以,我们做完最大匹配后,我们只要从未被匹配点按未匹配边,匹配边相间dfs下去,找到的所有和起点属于同一点集的点也是ans,问题得解
const dx:array[..] of integer=(,,-,);
dy:array[..] of integer=(,-,,);
type node=record
point,next:longint;
end; var a:array[..,..] of longint;
edge:array[..] of node;
ty,p,cx,cy,wx,wy:array[..] of longint;
v:array[..] of boolean;
k,len,x,y,i,j,n,m,w,r,t:longint;
s:string; procedure add(x,y:longint);
begin
inc(len);
edge[len].point:=y;
edge[len].next:=p[x];
p[x]:=len;
end; function find(x:longint):longint; //匈牙利
var i,y:longint;
begin
i:=p[x];
while i<>- do
begin
y:=edge[i].point;
if not v[y] then
begin
v[y]:=true;
if (cy[y]=-) or (find(cy[y])=) then
begin
cx[x]:=y;
cy[y]:=x;
exit();
end;
end;
i:=edge[i].next;
end;
exit();
end; procedure dfsx(x:longint);
var i,y:longint;
begin
v[x]:=true;
i:=p[x];
while i<>- do
begin
y:=edge[i].point;
if (cy[y]<>-) and not v[cy[y]] then dfsx(cy[y]);
i:=edge[i].next;
end;
end; procedure dfsy(y:longint);
var i,x:longint;
begin
v[y]:=true;
i:=p[y];
while i<>- do
begin
x:=edge[i].point;
if (cx[x]<>-) and not v[cx[x]] then dfsy(cx[x]);
i:=edge[i].next;
end;
end; begin
fillchar(p,sizeof(p),);
readln(n,m);
for i:= to n do
begin
readln(s);
for j:= to m do
if s[j]='.' then
begin
inc(k);
a[i,j]:=k;
wx[k]:=i;
wy[k]:=j;
ty[k]:=(i+j) mod ; //划分点集
end;
end;
r:=k;
for i:= to n do
for j:= to m do
if ((i+j) mod =) and (a[i,j]>) then
begin
inc(t);
for k:= to do
begin
x:=i+dx[k];
y:=j+dy[k];
if a[x,y]> then
begin
add(a[i,j],a[x,y]);
add(a[x,y],a[i,j]);
end;
end;
end;
fillchar(cx,sizeof(cx),);
fillchar(cy,sizeof(cy),); for i:= to r do
if (cx[i]=-) and (ty[i]=) then
begin
fillchar(v,sizeof(v),false);
w:=w+find(i);
end;
if (w=t) and (r-t=t) then
begin
writeln('LOSE');
halt;
end;
writeln('WIN');
fillchar(v,sizeof(v),false);
for i:= to r do
if (cx[i]=-) and (ty[i]=) then dfsx(i);
for i:= to r do
if (cy[i]=-) and (ty[i]=) then dfsy(i);
for i:= to r do
if v[i] then writeln(wx[i],' ',wy[i]);
end.
bzoj1443的更多相关文章
- BZOJ1443 [JSOI2009]游戏Game 【博弈论 + 二分图匹配】
题目链接 BZOJ1443 题解 既然是网格图,便可以二分染色 二分染色后发现,游戏路径是黑白交错的 让人想到匹配时的增广路 后手要赢[指移动的后手],必须在一个与起点同色的地方终止 容易想到完全匹配 ...
- 【BZOJ1443】游戏(二分图匹配,博弈论)
[BZOJ1443]游戏(二分图匹配,博弈论) 题面 BZOJ 题解 很明显的二分图博弈问题. 发现每次移动一定是从一个黑点到达一个白点,或者反过来. 所以可以对于棋盘进行染色然后连边. 考虑一下必胜 ...
- BZOJ1443: [JSOI2009]游戏Game
如果没有不能走的格子的话,和BZOJ2463一样,直接判断是否能二分图匹配 现在有了一些不能走的格子 黑白染色后求出最大匹配 如果是完备匹配,则无论如何后手都能转移到1*2的另一端,故先手必输 否则的 ...
- BZOJ1443 游戏game (二分图染色+匈牙利算法)
先对整幅图进行二分图染色,再跑一遍匈牙利算法.如果最大匹配数=点数*2,那么输出WIN. 对于任何一个非必须在最大匹配上的点,即为所求的点. Program Test375num2; type arr ...
- 【BZOJ1443】[JSOI2009]游戏Game(二分图+博弈)
BZOJ 题意: 给出一个\(n*m\)的网格,其中有一些障碍点. 现在两个人玩游戏,首先先手选定一个点,然后从后手开始轮流移动,不能移动者即输掉这次游戏. 规定不能移动到那些之前已经到过的格子上. ...
- 匈牙利算法(codevs2776)
type node=^link; link=record des:longint; next:node; end; var n,m,i,t,num:longint; p:node; nd:..] of ...
- @codeforces - 1161F@ Zigzag Game
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 2n 个结点的完全二分图,1~n 在左边,n+1~2n ...
随机推荐
- C# 编码约定
参考自 MSDN https://msdn.microsoft.com/zh-cn/library/ff926074.aspx , 只摘要个人觉得有用部分 命名约定 在不包括 using 指令 ...
- Flexbox介绍
CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式.对于很多应用来讲,弹性盒改进了盒模型,既不使用浮动 ...
- IO流06_处理流
[处理流] 处理流可以隐藏底层设备上节点流的差异,并对外提供更加方便的输入/输出的方法. 使用处理流的思路: 使用处理流来包装节点流,程序通过处理流来执行输入输出功能,让节点流与底层的I/O设备.文件 ...
- JSP编程中常用的JavaScript技术(转载)
1.<tronMouseOver=this.style.backgroundColor=’#FFFFFF’ onMouseOut=this.style.backgroundColor=”> ...
- OpenJudge 2774 木材加工
1.链接: http://bailian.openjudge.cn/practice/2774/ 2.题目: 总Time Limit: 1000ms Memory Limit: 65536kB Des ...
- Headfirst设计模式的C++实现——适配器(Adapter)
duck.h #ifndef _DUCK_H_ #define _DUCK_H_ class DUCK { public: ; ; }; #endif mallard_duck.h #ifndef _ ...
- 使用thinkPHP实现数据更新一例【原创】
在上一篇文章中我们实现了数据的删除和批量删除,这一篇文章我们将实现数据的更新. 首先依然是预期效果图: 点击修改后进入modi.html页面,然后进行修改,如此处修改了真实姓名这一属性: 点击保存: ...
- Eclipse代码自动提示
发现了一个好用的快捷键,不用跳转到源文件就可以看源代码:先按shift键,然后鼠标点击要看的代码,即可.
- centos6.3安装openvpn客户端
centos6.3安装openvpn客户端 Centos 默认是没有提供Openvpn的,而且在yum 的源里面也没有openvpn ,如果想使用yum安装的话要首先安装EPEL这个东西.www.2c ...
- 3d旋转--transform-style: preserve-3d,translate3d(x,y,z),perspective()
transform-style: preserve-3d,translate3d(x,y,z),perspective() 让其倾斜的核心:加perspective(600px)让其动的核心:rans ...