Description

[JSOI2009]游戏Game_博弈

Input

输入数据首先输入两个整数N,M,表示了迷宫的边长。 接下来N行,每行M个字符,描述了迷宫。

Output

若小AA能够赢得游戏,则输出一行"WIN",然后输出所有可以赢得游戏的起始位置,按行优先顺序输出 每行一个,否则输出一行"LOSE"(不包含引号)。

Sample Input

3 3
.##
...
#.#

Sample Output

WIN
2 3
3 2

HINT

对于100%的数据,有1≤n,m≤100。 对于30%的数据,有1≤n,m≤5。

这道题和[NOI2011]兔兔与蛋蛋游戏很像

首先黑白染色

同样的,对于一个点,如果它不一定构成最大匹配

也就是ban掉该点后还有最大匹配

那么它就是后手必胜

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 struct Node
 8 {
 9   int next,to;
10 }edge[100001];
11 int head[10001],num,n,m,x,y,id[101][101],cnt,cx[10001],tot;
12 bool vis[10001];
13 char s[1001];
14 void add(int u,int v)
15 {
16   num++;
17   edge[num].next=head[u];
18   head[u]=num;
19   edge[num].to=v;
20 }
21 bool dfs(int x)
22 {int i;
23   for (i=head[x];i;i=edge[i].next)
24     {
25       int v=edge[i].to;
26       if (vis[v]==0)
27     {
28       vis[v]=1;
29       if (!cx[v]||dfs(cx[v]))
30         {
31           cx[x]=v;cx[v]=x;
32           return 1;
33         }
34     }
35     }
36   return 0;
37 }
38 int main()
39 {int i,j,flag=0;
40   cin>>n>>m;
41   for (i=1;i<=n;i++)
42     {
43       scanf("%s",s+1);
44       for (j=1;j<=m;j++)
45     {
46       if (s[j]=='.') id[i][j]=++cnt;
47     }
48     }
49   for (i=1;i<=n;i++)
50     {
51       for (j=1;j<=m;j++)
52     if (id[i][j])
53       {
54         if (i>1&&id[i-1][j]) add(id[i][j],id[i-1][j]);
55         if (i<n&&id[i+1][j]) add(id[i][j],id[i+1][j]);
56         if (j>1&&id[i][j-1]) add(id[i][j],id[i][j-1]);
57         if (j<m&&id[i][j+1]) add(id[i][j],id[i][j+1]);
58       }
59     }
60   for (i=1;i<=n;i++)
61     {
62       for (j=1;j<=m;j++)
63     if (id[i][j]&&(i+j)%2)
64       {
65         memset(vis,0,sizeof(vis));
66         dfs(id[i][j]);
67       }
68     }
69   for (i=1;i<=n;i++)
70     {
71       for (j=1;j<=m;j++)
72     if (id[i][j])
73     {
74           memset(vis,0,sizeof(vis));
75           int u=id[i][j],v=cx[id[i][j]];
76            vis[u]=1;
77           if (!cx[u]||dfs(v))
78         {
79           cx[u]=0;
80           if (flag==0)
81             cout<<"WIN\n";
82           flag=1;
83           printf("%d %d\n",i,j);
84         }
85     }
86     }
87   if (flag==0) cout<<"LOSE";
88 }