首先要思考的问题肯定是,什么点可以是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的更多相关文章

  1. BZOJ1443 [JSOI2009]游戏Game 【博弈论 + 二分图匹配】

    题目链接 BZOJ1443 题解 既然是网格图,便可以二分染色 二分染色后发现,游戏路径是黑白交错的 让人想到匹配时的增广路 后手要赢[指移动的后手],必须在一个与起点同色的地方终止 容易想到完全匹配 ...

  2. 【BZOJ1443】游戏(二分图匹配,博弈论)

    [BZOJ1443]游戏(二分图匹配,博弈论) 题面 BZOJ 题解 很明显的二分图博弈问题. 发现每次移动一定是从一个黑点到达一个白点,或者反过来. 所以可以对于棋盘进行染色然后连边. 考虑一下必胜 ...

  3. BZOJ1443: [JSOI2009]游戏Game

    如果没有不能走的格子的话,和BZOJ2463一样,直接判断是否能二分图匹配 现在有了一些不能走的格子 黑白染色后求出最大匹配 如果是完备匹配,则无论如何后手都能转移到1*2的另一端,故先手必输 否则的 ...

  4. BZOJ1443 游戏game (二分图染色+匈牙利算法)

    先对整幅图进行二分图染色,再跑一遍匈牙利算法.如果最大匹配数=点数*2,那么输出WIN. 对于任何一个非必须在最大匹配上的点,即为所求的点. Program Test375num2; type arr ...

  5. 【BZOJ1443】[JSOI2009]游戏Game(二分图+博弈)

    BZOJ 题意: 给出一个\(n*m\)的网格,其中有一些障碍点. 现在两个人玩游戏,首先先手选定一个点,然后从后手开始轮流移动,不能移动者即输掉这次游戏. 规定不能移动到那些之前已经到过的格子上. ...

  6. 匈牙利算法(codevs2776)

    type node=^link; link=record des:longint; next:node; end; var n,m,i,t,num:longint; p:node; nd:..] of ...

  7. @codeforces - 1161F@ Zigzag Game

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 2n 个结点的完全二分图,1~n 在左边,n+1~2n ...

随机推荐

  1. JS基本类型和引用类型的值

    JS中可以把变量分成两部分,基本类型和引用类型. 基本类型比较简单,包括:Undefined.Null.Boolean.Number和String,基本类型值就是简单的数据段:引用类型值可能由多个值构 ...

  2. [Guava官方文档翻译] 3. 前置条件检查(Preconditions Explained)

    本文地址:http://www.cnblogs.com/hamhog/p/3536964.html 前置条件检查 Guava提供了一些检查前置条件的utilities.我们强烈建议静态import这些 ...

  3. RabbitMQ远程访问配置

    1 首先创建一个新的账户 并给上Administrator标签 2然后给这个新账户添加虚拟主机访问权限 3在windows 下的 rabbitmq安装文件下的etc文件下的配置文件添加以下 [    ...

  4. 如何在Linux下创建与解压zip, tar, tar.gz和tar.bz2文件

    这么多年来,数据压缩对我们来说是非常有用的.无论是在邮件中发送的图片用的zip文件还是在服务器压缩数据文件,我们都可以让下载更容易或者有效的节约磁盘空间.某些压缩格式有时允许我们以60%的比率(甚至更 ...

  5. busbox编译出错,arm-linux-未找到命令

    1.问题:/opt/FriendlyARM/mini6410/linux/busybox-1.17.2/scripts/gcc-version.sh: 行 11: arm-linux-gcc: 未找到 ...

  6. sae-服务器php运行环境配置

    config.yaml 语法- OPTION: ARG1 ARG2 ... - OPTION: if (CONDICTIONs) ACTION CONDITION可以是以下任意一种: 使用 == 和 ...

  7. 用PHP实现单向链表

    供参考,代码还可继续打磨 同时放在了我的github上:https://github.com/hheedat/demo/blob/master/learn_php/58_linked_list.php ...

  8. Ms SQLServer中的Union和Union All的使用方法和区别

    Ms SQLServer中的Union和Union All的使用方法和区别 SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 ...

  9. Nginx+uWSIG+Django+websocket的实现

    1.Django+websocket django-websocket dwebsocket django-websocket是旧版的,现在已经没有人维护,dwebsocket是新版的,推荐使用dwe ...

  10. mysql将多张表COUNT的数据相加

    由于数据量过大,我们将根据用户id 将数据存储在不同的表中,根据用户id模10的余数作为表的后缀.有如下十张表:test_0, test_1, ... ,test_9现在需要根据某个条件查询统计数据我 ...