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
", i, j);
            }
        }
    }
    return 0;
}


/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/9460332.html