BZOJ 4823 老C的方块
把格子分成四类 第一类是蓝线左右的相邻两个格子 第二类为与蓝线左边格子相邻的点 第三类为与蓝线右边格子相邻的点
建边就S朝第二类每个点建边 第二类每个点朝其相邻的第一类建边 第一类从左格子朝右格子建边 第一类朝与其相邻的第三类建边 第三类朝T建边
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef int JQK; const int dir[4][2] = { 0, -1, -1, 0, 0, 1, 1, 0 }; struct node { int x, y, w, color; } p[100005]; int n, m; map<pair<int, int>, int> mp; namespace dinic { const int MAXN = 100500; const int MAXM = 1000500; const int INF = 1000000050; int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << 1], nxt[MAXM << 1], ed = 1; int S, T, MAXP; JQK f[MAXM << 1]; inline void addedge(int u, int v, JQK cap) { to[++ed] = v; nxt[ed] = Head[u]; Head[u] = ed; f[ed] = cap; to[++ed] = u; nxt[ed] = Head[v]; Head[v] = ed; f[ed] = 0; return; } inline bool BFS() { int u; for (int i = 0; i <= MAXP + 1; i++) { lev[i] = -1; } //memset(lev, -1, sizeof(lev)); queue<int>q; lev[S] = 0; q.push(S); while (q.size()) { u = q.front(); q.pop(); for (int i = Head[u]; i; i = nxt[i]) if (f[i] && lev[to[i]] == -1) { lev[to[i]] = lev[u] + 1; q.push(to[i]); /* if (to[i] == T) { return 1; } magic one way optimize */ } } for (int i = 0; i <= MAXP + 1; i++) { cur[i] = Head[i]; } //memcpy(cur, Head, sizeof Head); return lev[T] != -1; } inline JQK DFS(int u, JQK maxf) { if (u == T || !maxf) { return maxf; } JQK cnt = 0, tem; for (int &i = cur[u]; i; i = nxt[i]) if (f[i] && lev[to[i]] == lev[u] + 1) { tem = DFS(to[i], min(maxf, f[i])); maxf -= tem; f[i] -= tem; f[i ^ 1] += tem; cnt += tem; if (!maxf) { break; } } if (!cnt) { lev[u] = -1; } return cnt; } JQK Dinic() { JQK ans = 0; while (BFS()) { ans += DFS(S, INF); } return ans; } void init(int SS, int TT) { for (int i = 0; i <= MAXP + 1; i++) { Head[i] = 0; } ed = 1; S = SS; T = TT; return; } void work() { for (int i = 1; i <= n; i++) { if (p[i].color == 0) { addedge(i, T, p[i].w); } else if (p[i].color == 1) { addedge(S, i, p[i].w); } else if (p[i].color == 2) { for (int j = 0; j < 4; j++) { int dx = p[i].x + dir[j][0]; int dy = p[i].y + dir[j][1]; int aim = mp[make_pair(dx, dy)]; if (aim == 0) { continue; } else if (p[aim].color == 1) { addedge(aim, i, INF); } else if (p[aim].color == 3) { addedge(i, aim, min(p[aim].w, p[i].w)); } } } else { for (int j = 0; j < 4; j++) { int dx = p[i].x + dir[j][0]; int dy = p[i].y + dir[j][1]; int aim = mp[make_pair(dx, dy)]; if (aim == 0) { continue; } else if (p[aim].color == 0) { addedge(i, aim, INF); } } } } printf("%d\n", Dinic()); } } int get_color(int x, int y) { if (x & 1) { return y % 4 == 1 || y % 4 == 2; } else { return y % 4 == 3 || y % 4 == 0; } } int main() { int r, c; int s, t; int x, y, w; while (scanf("%d %d %d", &c, &r, &n) == 3) { mp.clear(); for (int i = 1; i <= n; i++) { scanf("%d %d %d", &y, &x, &w); p[i].x = x, p[i].y = y, p[i].w = w; mp[make_pair(x, y)] = i; if ((x + y + 1) & 1) { p[i].color = get_color(x, y) ? 3 : 1; } else { p[i].color = get_color(x, y) ? 2 : 0; } //cout << p[i].color << endl; } dinic::MAXP = n + 2; dinic::init(n + 1, n + 2); dinic::work(); } return 0; }