[NOI2011] Bunny and Egg game

Portal

Game theory can be directly dfs 75 points (natural goose game theory I learned very pie)

#include<bits/stdc++.h>
#define LL long long
#define INF 10000
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}  
char s[45];
int lr[]={0,0,1,-1},ud[]={1,-1,0,0},ans[1003],tu[43][43],sg[43];
int X,Y,tot=0,n,m;
int dfs(int x,int y,int op)
{
    for ( int I = 0 ; I < . 4 ; ++ I) 
    { 
        int XX UD = X + [I], Y + YY = LR [I];
         IF (XX < . 1 || XX> n-YY || < . 1 | | YY> m || TU [XX] [YY] = OP)! Continue ; 
        the swap (TU [XX] [YY], TU [X] [Y]); 
        IF (DFS (XX, YY, OP ^! . 1 )) {swap (tu [xx] [YY], TU [X] [Y]); return  . 1 ;} // down recursively obtained every situation, which is a winning or losing is determined 
        swap (tu [xx] [YY], TU [X] [Y]); 
    } 
    return  0 ; 
} 
int main () 
{ 
//    freopen("game.in","r",stdin);
//    freopen("game.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;++i)
    {
        scanf("%s",s+1);
        for(int j=1;j<=m;++j)
        {
            if(s[j]=='X')tu[i][j]=1;//黑棋 
            else if(s[j]=='.'2) you [i] [j] =, = X-I, the Y = J; // spaces 
        } 
    } 
    int OP = Read ();
     for ( int I = . 1 ; I <= OP; ++ I) 
    { 
        int X = Read (), Y = Read () ; 
        SG [I] = DFS (X-, the Y, 0 ); 
        the swap (TU [X] [Y], TU [X-] [the Y]); 
        X- = X; the Y = Y;
         IF (SG [I] && DFS ( X-, the Y, . 1 )) ANS [TOT ++] = I; // go before a rabbit win state, then go Egg win state is 
        X = Read (), Y = Read (); 
        the swap (TU [X] [Y], TU [X-] [the Y]); 
        X- = X; the Y = Y; 
    } 
    the printf ("%d\n",tot);
    for(int i=1;i<=tot;++i)
      printf("%d\n",ans[i]);    
} 
/*
*/
75 points

Then Solution n is a bipartite graph. . . Who'd have thought wow this is a bipartite graph

Let us carefully analyze:

Sequentially shifting each white cell Haig, when the last stop can not be moved, and through each grid only once (inductive sensing) corresponds to a black and white checkerboard staining -> thought bipartite FIG.

Each exchange is not so much space, and other black and white grid, as it is a space walk on the black and white grid. (The first step in the space itself)

We can be considered the first step in Haig, then take the checkered alternately, if finally went Haig explained lose Bunny (Bunny mobile white grid).

Then bipartite graph matching ensures finally went white grid must, as from Haig (odd steps are required for each road)

Lattice is the equivalent of walking in augmenting the way to go if the current x, y sure on the maximum matching (augmented in the way and no other way of augmenting may replace it), it will now be to win state.

Then, for each step for determining, if the i-th step Egg and rabbit are win state, described in the rabbit before walking step i is to win state, go to step i win state that the balls .

Meet the subject requirements, the cumulative answer.

#include<bits/stdc++.h>
#define N 43
#define LL long long
#define INF 10000
using namespace std;
int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}  
struct EDGE{
    int nextt,to;
}w[N*N*4];
char s[N];
int lr[]={0,0,1,-1},ud[]={1,-1,0,0},ans[1003],tu[N][N],head[N*N],ord[N][N],vis[N*N],match[N*N],ban[N*N],win[1003];
int X,Y,tot=0,n,m,ndnum=0,res=0,timer=0;
void add(int a,int b)
{
    tot++;
    w[tot].nextt=head[a];
    w[tot].to=b;
    head[a]=tot;
}
void jian_tu()//建二分图 
{
    for(int i=1;i<=n;++i)
      for(int j=1;j<=m;++j)
      {
          if(!tu[i][j])continue;
          for(int k=0;k<4;++k)
        {
            int xx=i+ud[k],yy=j+lr[k];
            if(xx<1||xx>n||yy<1||yy>m||tu[xx][yy])continue;
            add(ord[i][j],ord[xx][yy]);
            add(ord[xx][yy],ord[i][j]);
        }
      }
}
int dfs(int x)
{
    if(vis[x]==timer||ban[x])return 0;
    vis[x]=timer;
    for(int i=head[x];i;i=w[i].nextt)
    {
        int v=w[i].to;
        if(ban[v])continue;
        if(!match[v]||dfs(match[v]))
        {
            match[v]=x;match[x]=v;
            return 1;
        }
    }
    return 0;
}
int main()
{
//    freopen("game.in","r",stdin);
//    freopen("game.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;++i)
    {
        scanf("%s",s+1);
        for(int j=1;j<=m;++j)
        {
            ord[i][j]=++ndnum; 
            if(s[j]=='X')tu[i][j]=1;//黑棋 
            else if(s[j]=='.')tu[i][j]=2,X=i,Y=j;//空格 
        } 
    }
    jian_tu();
    for(int i=1;i<=n;++i)
      for(int j=1;j<=m;++j)
        if(tu[i][j])timer++,dfs(ord[i][j]);
    int op=read();
    for(int i=1;i<=op*2;++i)
    {
        int id=ord[X][Y];
        ban[id]=1;
        if(match[id])
        {
            int v=match[id];
            match[id]=match[v]=0;
            ++timer;
            win[i]=(!dfs(v));//在增广路上且不可代替 
        }
        X=read();Y=read();
    }
    for(int i=1;i<=op;++i)
      if(win[2*i-1]&&win[2*i])ans[++res]=i;
    printf("%d\n",res);
    for(int i=1;i<=res;++i)
      printf("%d\n",ans[i]);    
} 
AC bipartite graph

 

Guess you like

Origin www.cnblogs.com/yyys-/p/11514768.html