Luogu4055 game (bipartite game)
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 }