zoukankan      html  css  js  c++  java
  • bzoj2437 [Noi2011]兔兔与蛋蛋

    二分图博弈果然都是一个套路,必经点必胜,非必经点必败,

    但是肯定不能每走一步就重新建图判断必胜还是必败,那么我们可以这样:每走一步就把这个点删掉,然后find他原来的匹配,如果找不到,就说明他是必经点,否则就是非必经点。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #define N 1601
     7 using namespace std;
     8 int e=1,head[N];
     9 struct edge{int v,next;}ed[N*4];
    10 void add(int u,int v){ed[e].v=v;ed[e].next=head[u];head[u]=e++;}
    11 int pp[N],del[N],id[41][41];
    12 bool vis[N],ans[N];
    13 bool find(int x){
    14     for(int i=head[x];i;i=ed[i].next){
    15         int v=ed[i].v;
    16         if(del[v]||vis[v])continue;vis[v]=1;
    17         if(!pp[v]||find(pp[v])){
    18             pp[v]=x;pp[x]=v;
    19             return 1;
    20         }
    21     }return 0;
    22 }
    23 int a[41][41],be,n,m,T,sx,sy,tot1,tot2,tot;
    24 char ch[41];
    25 bool check(int i,int j){return ((i+j)&1)^a[i][j]==be;}
    26 int f[N],f_cnt;
    27 int main(){
    28     scanf("%d%d",&n,&m);
    29     for(int i=1;i<=n;i++){
    30         scanf("%s",ch+1);
    31         for(int j=1;j<=m;j++)
    32             if(ch[j]=='O')a[i][j]=1;
    33             else if(ch[j]=='X')a[i][j]=0;
    34             else sx=i,sy=j;
    35     }
    36     be=(sx+sy)&1;
    37     for(int i=1;i<=n;i++)
    38         for(int j=1;j<=m;j++)if(check(i,j))
    39             if(a[i][j])id[i][j]=++tot1;
    40             else id[i][j]=++tot2;
    41     for(int i=1;i<=n;i++)
    42         for(int j=1;j<=m;j++)if(check(i,j)&&(!a[i][j]))
    43             id[i][j]+=tot1;
    44     tot=tot1+tot2;
    45     for(int i=1;i<=n;i++)
    46         for(int j=1;j<=m;j++)if(id[i][j]){
    47             if(id[i+1][j])add(id[i][j],id[i+1][j]);
    48             if(id[i][j+1])add(id[i][j],id[i][j+1]);
    49             if(id[i-1][j])add(id[i][j],id[i-1][j]);
    50             if(id[i][j-1])add(id[i][j],id[i][j-1]);
    51         }
    52     for(int i=1;i<=tot1;i++){
    53         memset(vis,0,sizeof vis);
    54         find(i);
    55     }
    56     scanf("%d",&T);T<<=1;
    57     for(int i=1,x,y;i<=T;i++){
    58         int now=id[sx][sy],p=pp[now];
    59         del[now]=1;pp[now]=pp[p]=0;
    60         if(!p)ans[i]=0;
    61         else{
    62             memset(vis,0,sizeof vis);
    63             ans[i]=find(p)^1;
    64         }
    65         scanf("%d%d",&sx,&sy);
    66     }
    67     for(int i=1;i<=T;i+=2)
    68         if(ans[i]&&ans[i+1])f[++f_cnt]=(i+1)>>1;
    69     printf("%d
    ",f_cnt);
    70     for(int i=1;i<=f_cnt;i++)
    71         printf("%d
    ",f[i]);
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    JavaScript
    并发编程基础
    基于 TCP & UDP 协议的 socket 通信
    struct 模块 & subprocess 模块
    Python中的异常处理
    网络编程基础
    Json 模块补充
    冒泡排序
    OOP 反射 & 元类
    OOP 内置函数
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8352969.html
Copyright © 2011-2022 走看看