1443: [JSOI2009]游戏Game
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1245 Solved: 575
[ Submit][ Status][ Discuss]
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。
Source
#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef pair< int, int > pp;
int n, m, top, ord[105][105], head[10005], tot;
vector< int > pe;
pp arc[10005];
struct Node
{
int y, nxt;
Node() { }
Node( int y, int nxt ) : y(y), nxt(nxt) { }
} e[100005];
void Adde( int x, int y )
{
e[++top] = Node(y, head[x]), head[x] = top;
e[++top] = Node(x, head[y]), head[y] = top;
}
char s[105][105];
bool vis[10005], ans[10005];
int mat[10005];
bool Find( int u )
{
for(int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].y;
if(vis[v]) continue;
vis[v] = 1;
if(!mat[v] || Find(mat[v])) return (mat[u] = v, mat[v] = u);
}
return false;
}
void Hung()
{
for(int i = 0; i < (int)pe.size(); ++i)
{
if(mat[pe[i]]) continue;
memset(vis, 0, sizeof(vis));
tot += Find(pe[i]);
}
}
void Dfs( int u )
{
ans[u] = 1;
for(int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].y;
if(mat[v] && !ans[mat[v]]) Dfs(mat[v]);
}
}
int main()
{
cin >> 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)
{
ord[i][j] = (i - 1) * m + j;
arc[ord[i][j]] = mp(i, j);
if(s[i][j] == '.')
{
if(s[i + 1][j] == '.') Adde(ord[i][j], ord[i][j] + m);
if(s[i][j + 1] == '.') Adde(ord[i][j], ord[i][j] + 1);
if(s[i - 1][j] == '.') Adde(ord[i][j], ord[i][j] - m);
if(s[i][j - 1] == '.') Adde(ord[i][j], ord[i][j] - 1);
pe.push_back(ord[i][j]);
}
}
Hung();
if(tot * 2 == pe.size())
{
puts("LOSE");
return 0;
}
puts("WIN");
for(int i = 0; i < (int)pe.size(); ++i)
if(!mat[pe[i]]) Dfs(pe[i]);
for(int i = 0; i < (int)pe.size(); ++i)
if(ans[pe[i]]) printf( "%d %d\n", arc[pe[i]].first, arc[pe[i]].second );
return 0;
}