【题目链接】
【思路要点】
- 补档博客,无题解。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 45 #define MAXK 1005 #define MAXP 1605 #define INF 1e9 struct edge {int dest, flow; unsigned pos; }; vector <edge> a[MAXP]; char mp[MAXN][MAXN]; bool visited[MAXN][MAXN]; unsigned curr[MAXP]; int d[MAXP]; int n, m, homex, homey, s, t; bool bfs() { static int q[MAXN]; int l = 0, r = 0; memset(d, 0, sizeof(d)); q[0] = s; d[s] = 1; while (l <= r) { int tmp = q[l]; for (unsigned i = 0; i < a[tmp].size(); i++) if (a[tmp][i].flow && d[a[tmp][i].dest] == 0) { q[++r] = a[tmp][i].dest; d[q[r]] = d[tmp] + 1; } l++; } return d[t] != 0; } int dinic(int pos, int limit) { if (pos == t) return limit; int used = 0, tmp; for (unsigned &i = curr[pos]; i < a[pos].size(); i++) if (a[pos][i].flow && d[pos] + 1 == d[a[pos][i].dest] && (tmp = dinic(a[pos][i].dest, min(limit - used, a[pos][i].flow)))) { a[pos][i].flow -= tmp; a[a[pos][i].dest][a[pos][i].pos].flow += tmp; used += tmp; if (used == limit) return used; } return used; } int point(int x, int y) { return (x - 1) * m + y; } void insert(int x, int y) { a[x].push_back((edge) {y, 1, a[y].size()}); a[y].push_back((edge) {x, 0, a[x].size() - 1}); } bool legal(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m; } void work(int x, int y) { visited[x][y] = true; int tmp = point(x, y); if (mp[x][y] == mp[homex][homey]) { insert(s, tmp); if (legal(x, y - 1) && mp[x][y] != mp[x][y - 1]) { insert(tmp, point(x, y - 1)); if (!visited[x][y - 1]) work(x, y - 1); } if (legal(x, y + 1) && mp[x][y] != mp[x][y + 1]) { insert(tmp, point(x, y + 1)); if (!visited[x][y + 1]) work(x, y + 1); } if (legal(x - 1, y) && mp[x][y] != mp[x - 1][y]) { insert(tmp, point(x - 1, y)); if (!visited[x - 1][y]) work(x - 1, y); } if (legal(x + 1, y) && mp[x][y] != mp[x + 1][y]) { insert(tmp, point(x + 1, y)); if (!visited[x + 1][y]) work(x + 1, y); } } else { insert(tmp, t); if (legal(x, y - 1) && mp[x][y] != mp[x][y - 1]) if (!visited[x][y - 1]) work(x, y - 1); if (legal(x, y + 1) && mp[x][y] != mp[x][y + 1]) if (!visited[x][y + 1]) work(x, y + 1); if (legal(x - 1, y) && mp[x][y] != mp[x - 1][y]) if (!visited[x - 1][y]) work(x - 1, y); if (legal(x + 1, y) && mp[x][y] != mp[x + 1][y]) if (!visited[x + 1][y]) work(x + 1, y); } } bool func(char type) { mp[homex][homey] = type; s = 0, t = n * m + 1; memset(visited, false, sizeof(visited)); for (int i = s; i <= t; i++) a[i].clear(); work(homex, homey); int ans = 0; while (bfs()) { memset(curr, 0, sizeof(curr)); ans += dinic(s, INF); } memset(visited, false, sizeof(visited)); for (int i = s; i <= t; i++) a[i].clear(); work(homex, homey); a[point(homex, homey)].clear(); int tans = 0; while (bfs()) { memset(curr, 0, sizeof(curr)); tans += dinic(s, INF); } return ans != tans; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("\n"); for (int j = 1; j <= m; j++) { scanf("%c", &mp[i][j]); if (mp[i][j] == '.') { homex = i; homey = j; } } } int q, cnt = 0; static int ans[MAXK]; scanf("%d", &q); for (int i = 1; i <= q; i++) { int x, y; scanf("%d%d", &x, &y); bool flg = func('X'); swap(mp[x][y], mp[homex][homey]); homex = x; homey = y; if (flg && func('O')) ans[++cnt] = i; scanf("%d%d", &x, &y); swap(mp[x][y], mp[homex][homey]); homex = x; homey = y; } printf("%d\n", cnt); for (int i = 1; i <= cnt; i++) printf("%d\n", ans[i]); return 0; }