meaning of the title
Sol
For the first time, I did the game on the bipartite graph.. It's really strange..
First, color the picture black and white.
For a point, if it must be on the maximum match, then Bob will win. Because Bob can go all the way along the matching edge, Alice can only go along the non matching edge. In the end, Alice must not be able to move.
Otherwise Alice will win. I can't prove this, but I can't give a counterexample to qwq. After playing with some data, it is found that Alice always has a way to go through some mismatches and kill Bob.
So how to find points that are not necessarily on the maximum match? First, we get a maximum match. The conclusion is that dfs starts from all the points that are not on the maximum match, and passes through the crossing edge (the matching edge of the target point) to the point that is not necessarily on the maximum match. (there is always a way to make this point the best match)
And then go straight to Hungary
#include<bits/stdc++.h> #define LL long long using namespace std; const int MAXN = 1001, INF = 1e9 + 7, mod = 998244353; template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;} template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;} template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;} template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);} template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;} template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;} inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M; char s[MAXN][MAXN]; vector<int> v[MAXN * MAXN]; void AE(int x, int y) { v[x].push_back(y); v[y].push_back(x); } int vis[MAXN * MAXN], link[MAXN * MAXN], tag[MAXN * MAXN], times; int id(int x, int y) { return (x - 1) * M + y; } bool Aug(int x) { for(auto &to : v[x]) { if(vis[to] == times) continue; vis[to] = times;//tag if(!link[to] || Aug(link[to])) {link[to] = x; link[x] = to; return 1;} } return 0; } void dfs(int x) { tag[x] = 1; for(auto &to : v[x]) if(!tag[link[to]]) dfs(link[to]); } int main() { N = read(); M = read(); 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] == '.') { if(i < N && s[i + 1][j] == '.') AE(id(i, j), id(i + 1, j)); if(j < M && s[i][j + 1] == '.') AE(id(i, j), id(i, j + 1)); } for(int i = 1; i <= N; i++) for(int j = 1; j <= M; j++) if(((i + j) & 1) && s[i][j] == '.') times++, Aug(id(i, j)); for(int i = 1; i <= N; i++) for(int j = 1; j <= M; j++) if(s[i][j] == '.' && !link[id(i, j)] && !tag[id(i, j)]) dfs(id(i, j)); int ans = 0; for(int i = 1; i <= N; i++) for(int j = 1; j <= M; j++) if(tag[id(i, j)]) ans++; cout << ans << '\n'; for(int i = 1; i <= N; i++) for(int j = 1; j <= M; j++) if(tag[id(i, j)]) cout << i << ' ' << j << '\n'; return 0; }