Luogu4055 game (bipartite game)

Consider the black and white coloring of non obstacle points and then do the maximum matching of bipartite graphs. Then it is concluded that the first step is to win if and only if it is not a perfect match, and the points that can be put are those that can not be matched

Starting from the non matching point, the second hand can only go to the matching point, so the first hand can go to the matching edge. Since the point that cannot be walked through is now a non matching point; This goes on until there is no way for the second hand to go, so the first hand will win

On the other hand, in the case of perfect matching, if the first hand is placed at any matching position, the second hand can walk along the matching edge, which becomes the above situation, that is, the second hand will win

Such problems can be summarized as:( A class of game problems that can be described by bipartite graphs )

1. The number of players is two, and both parties take turns to make decisions.
2. Game states (corresponding points) can be divided into two types (state space can be divided into two sets), corresponding to both sides of the bipartite graph (X set and Y set). Any legal decision (corresponding edge) makes the state jump from one class to another. (Because of this property, the problem can be described by bipartite graph)
3. You cannot transfer to the accessed status. (non repeatable access point)
4. Those who cannot be transferred will be punished.

 one #include<bits/stdc++.h> two  #define pa pair<int,int> three  #define CLR(a,x) memset(a,x,sizeof(a)) four  #define MP make_pair five  #define fi first six  #define se second seven  using  namespace std; eight typedef long  long ll; nine typedef unsigned long  long ull; ten typedef unsigned int ui; eleven typedef long  double ld; twelve  const  int maxn= one hundred and five ,maxp=1e4+ ten ; thirteen 
 fourteen inline char gc(){ fifteen      return getchar(); sixteen      static  const  int maxs= one << sixteen ; static  char buf[maxs],*p1=buf,*p2= buf; seventeen      return p1==p2&&(p2=(p1=buf)+fread(buf, one ,maxs,stdin),p1==p2)? EOF:*p1++ ; eighteen  } nineteen  inline ll rd(){ twenty ll x= zero ; char c=gc(); bool neg= zero ; twenty-one      while (c< ' zero ' ||c> ' nine ' ){ if (c== ' - ' ) neg= one ; c= gc();} twenty-two      while (c>= ' zero ' &&c<= ' nine ' ) x=(x<< one )+(x<< three )+c- ' zero ' ,c= gc(); twenty-three      return neg? (~x+ one ):x; twenty-four  } twenty-five 
 twenty-six  int N,M,id[maxn][maxn],pct,cnt[ two ]; twenty-seven  char mp[maxn][maxn]; twenty-eight  bool col[maxp],flag[maxp],ans[maxp]; twenty-nine  int eg[maxp* four ][ two ],egh[maxp],bel[maxp],ect; thirty 
 thirty-one inline void adeg( int a, int b){ thirty-two eg[++ect][ zero ]=b,eg[ect][ one ]=egh[a],egh[a]= ect; thirty-three  } thirty-four 
 thirty-five  bool dfs( int x){ thirty-six      for ( int i=egh[x]; i; i=eg[i][ one ]){ thirty-seven          int b=eg[i][ zero ]; if (flag[b]) continue ; thirty-eight flag[b]= one ; thirty-nine          if (!bel[b]|| dfs(bel[b])){ forty bel[b]=x,bel[x]= b; forty-one              return  one ; forty-two  } forty-three } return  zero ; forty-four  } forty-five 
 forty-six  int main(){ forty-seven      // freopen("","r",stdin);
 forty-eight N=rd(),M= rd(); forty-nine      for ( int i= one ; i<=N; i++) scanf( " %s " ,mp[i]+ one ); fifty      for ( int i= one ; i<=N; i++ ){ fifty-one          for ( int j= one ; j<=M; j++ ){ fifty-two              if (mp[i][j]== ' . ' ){ fifty-three id[i][j]=++ pct; fifty-four cnt[col[pct]=(i& one )^(j& one )]++ ; fifty-five                  if (i> one &&mp[i- one ][j]== ' . ' ) fifty-six adeg(id[i- one ][j],id[i][j]),adeg(id[i][j],id[i- one ][j]); fifty-seven                  if (j> one &&mp[i][j- one ]== ' . ' ) fifty-eight adeg(id[i][j- one ],id[i][j]),adeg(id[i][j],id[i][j- one ]); fifty-nine  } sixty  } sixty-one  } sixty-two      int nn= zero ; sixty-three      for ( int i= one ; i<=pct; i++ ){ sixty-four CLR(flag, zero ); sixty-five          if (col[i]) nn+= dfs(i); sixty-six  } sixty-seven      if (nn==cnt[ zero ]&&nn==cnt[ one ]) puts( " LOSE " ); sixty-eight      else { sixty-nine puts( " WIN " ); seventy          for ( int i= one ; i<=pct; i++ ){ seventy-one CLR(flag, zero ); seventy-two flag[i]= one ; seventy-three              if (!bel[i]||dfs(bel[i])) bel[i]= zero ,ans[i]= one ; seventy-four  } seventy-five          for ( int i= one ; i<=N; i++ ){ seventy-six              for ( int j= one ; j<=M; j++ ){ seventy-seven                  if (ans[id[i][j]]) printf( " %d %d\n " ,i,j); seventy-eight  } seventy-nine  } eighty  } eighty-one      return  zero ; eighty-two }

 

posted @ 2019-04-27 15:53   Ressed   Reading( two hundred and four Comments( zero edit   Collection   report