bzoj 1443 二分图博弈
这种两个人轮流走,不能走 走过的格子的大都是二分图博弈。。。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 100 + 7; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int n, m, tot, hs[N][N], match[N * N], f[N * N], ans[N * N]; int dx[] = {1, 0}, dy[] = {0, 1}; bool vis[N * N]; vector<int> edge[N * N]; char s[N][N]; int path(int u) { for(int i = 0; i < edge[u].size(); i++) { int v = edge[u][i]; if(!vis[v]) { vis[v] = true; if(match[v] == -1 || path(match[v])) { match[v] = u; return 1; } } } return 0; } void work(int u) { if(ans[u]) return; ans[u] = 1; for(int i = 0; i < edge[u].size(); i++) { int v = edge[u][i]; if(match[v] != -1) work(match[v]); } } int main() { memset(match, -1, sizeof(match)); 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] == '#') continue; hs[i][j] = ++tot; f[hs[i][j]] = (i ^ j) & 1; } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { if(s[i][j] == '#') continue; for(int k = 0; k < 2; k++) { int x = i + dx[k], y = j + dy[k]; if(hs[x][y]) { edge[hs[i][j]].push_back(hs[x][y]); edge[hs[x][y]].push_back(hs[i][j]); } } } } int cnt = 0; for(int i = 1; i <= tot; i++) { if(f[i]) { memset(vis, 0, sizeof(vis)); if(path(i)) cnt++; } } if(2 * cnt == tot) { puts("LOSE"); } else { puts("WIN"); for(int i = 1; i <= tot; i++) { if(match[i] != -1) match[match[i]] = i; } for(int i = 1; i <= tot; i++) { if(match[i] == -1) work(i); } for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { if(ans[hs[i][j]]) printf("%d %d\n", i, j); } } } return 0; } /* */