标签:
显然由‘.‘构成了一个二分图,求不走重复的先手必败点。
情况1 对于一个二分图最大匹配中的非必要点,先手每次只能移动到一条未走过的匹配边上(不可能从未匹配点沿匹配边走到其它未匹配点),后手则可以移动到匹配边另一侧,由于匹配边有限最终先手无法操作因此先手必败。
情况2 对于一个二分图最大匹配中的必要点,先手每次可以沿匹配边移动,后手只能走到一条未走过的匹配边上(从必要点沿匹配边走不会走到未匹配点),由于匹配边有限最终后手手无法操作因此先手必胜。
因此求出二分图最大匹配中的非必要点即为答案。可以先求出一个最大匹配,再从未匹配点出发走交错轨找其它非必要点。
#include<cstdio> int n,m; char s[128][128]; int xs[]={-1,0,1,0}; int ys[]={0,-1,0,1}; int px[128][128],py[128][128],d[128][128],now,v[128][128],ed[128][128]; bool dfs(int x,int y){ d[x][y]=now; if(px[x][y]&&d[px[x][y]][py[x][y]]!=now)return dfs(px[x][y],py[x][y]); for(int i=0;i<4;i++){ int x1=x+xs[i],y1=y+ys[i]; if(d[x1][y1]!=now&&s[x1][y1]==‘.‘&&!px[x1][y1]){ px[x][y]=x1;py[x][y]=y1; px[x1][y1]=x;py[x1][y1]=y; return 1; } } for(int i=0;i<4;i++){ int x1=x+xs[i],y1=y+ys[i]; if(d[x1][y1]!=now&&s[x1][y1]==‘.‘&&dfs(x1,y1)){ px[x][y]=x1;py[x][y]=y1; px[x1][y1]=x;py[x1][y1]=y; return 1; } } return 0; } void dfs2(int x,int y){ if(ed[x][y]||s[x][y]!=‘.‘)return; ed[x][y]=1; v[x][y]=1; for(int i=0;i<4;i++){ int x1=x+xs[i],y1=y+ys[i]; if(px[x1][y1])dfs2(px[x1][y1],py[x1][y1]); } } int main(){int a=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%s",s[i]+1); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(s[i][j]==‘.‘&&!px[i][j]){ ++now; a+=dfs(i,j); } } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(s[i][j]==‘.‘&&!px[i][j])v[i][j]=1; } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(s[i][j]==‘.‘&&!px[i][j])dfs2(i,j); } } bool win=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(v[i][j])win=1; } } puts(win?"WIN":"LOSE"); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(v[i][j])printf("%d %d\n",i,j); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/ccz181078/p/5424719.html