[JSOI2009]游戏Game
Description
Input
输入数据首先输入两个整数N,M,表示了迷宫的边长。 接下来N行,每行M个字符,描述了迷宫。
Output
若小AA能够赢得游戏,则输出一行"WIN",然后输出所有可以赢得游戏的起始位置,按行优先顺序输出 每行一个,否则输出一行"LOSE"(不包含引号)。
Sample Input
3 3
.##
...
#.#
.##
...
#.#
Sample Output
WIN
2 3
3 2
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 }