ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

显然由'.'构成了一个二分图,求不走重复的先手必败点。

情况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;
}

 

posted on 2016-04-23 15:20  nul  阅读(518)  评论(0编辑  收藏  举报