# Bzoj - 1443 [JSOI2009]游戏Game [二分图博弈]

190人阅读 评论(0)

## 1443: [JSOI2009]游戏Game

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1245  Solved: 575
[Submit][Status][Discuss]

3 3
.##
...
#.#

WIN
2 3
3 2

## Source

[Submit][Status][Discuss]

AA在非匹配点放下棋子是唯一选择，因为前面分析过放在匹配点一定输

#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 )
{
}

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;
}
﻿

个人资料
等级：
访问量： 5769
积分： 322
排名： 24万+
文章存档