很不争气地借用了别人家的题解。。
#include #include #include #include #include #include #include #include #define min(a,b) ((a) < (b) ? (a) : (b)) using namespace std; const int INF = ~0U>>1; const int maxn = 2E5 + 20; const int maxm = 2E6 + 20; struct E{ int to,cap,flow; E(){} E(int to,int cap,int flow): to(to),cap(cap),flow(flow){} }edgs[maxm]; struct Point{ int x,y; Point(){} Point(int x,int y): x(x),y(y){} bool operator < (const Point &B) const { if (x < B.x) return 1; if (x > B.x) return 0; return y < B.y; } }p[maxn]; int C,R,n,m,s,t,cnt,tot,L[maxn],cur[maxn],w[maxn],A[maxn],B[maxn]; queue Q; map M; vector v[maxn]; inline int getint() { char ch = getchar(); int ret = 0; while (ch < '0' || '9' < ch) ch = getchar(); while ('0' <= ch && ch <= '9') ret = ret * 10 + ch - '0',ch = getchar(); return ret; } inline void Add(int x,int y,int cap) { v[x].push_back(cnt); edgs[cnt++] = E(y,cap,0); v[y].push_back(cnt); edgs[cnt++] = E(x,0,0); } void Build() { for (int i = 1; i <= n; i++) { Add(A[i],B[i],w[i]); if (p[i].x % 4 == 1 && !(p[i].y & 1)) { Add(s,A[i],INF); if (M.count(Point(p[i].x,p[i].y - 1))) Add(B[i],A[M[Point(p[i].x,p[i].y - 1)]],w[i]); if (M.count(Point(p[i].x,p[i].y + 1))) Add(B[i],A[M[Point(p[i].x,p[i].y + 1)]],w[i]); if (M.count(Point(p[i].x - 1,p[i].y))) Add(B[i],A[M[Point(p[i].x - 1,p[i].y)]],w[i]); } else if (p[i].x % 4 == 0 && (p[i].y & 1)) { Add(s,A[i],INF); if (M.count(Point(p[i].x,p[i].y - 1))) Add(B[i],A[M[Point(p[i].x,p[i].y - 1)]],w[i]); if (M.count(Point(p[i].x,p[i].y + 1))) Add(B[i],A[M[Point(p[i].x,p[i].y + 1)]],w[i]); if (M.count(Point(p[i].x + 1,p[i].y))) Add(B[i],A[M[Point(p[i].x + 1,p[i].y)]],w[i]); } else if (p[i].x % 4 == 1 && (p[i].y & 1)) { if (M.count(Point(p[i].x + 1,p[i].y))) Add(B[i],A[M[Point(p[i].x + 1,p[i].y)]],w[i]); } else if (p[i].x % 4 == 0 && !(p[i].y & 1)) { if (M.count(Point(p[i].x - 1,p[i].y))) Add(B[i],A[M[Point(p[i].x - 1,p[i].y)]],w[i]); } else if (p[i].x % 4 == 2 && (p[i].y & 1)) { if (M.count(Point(p[i].x + 1,p[i].y))) Add(B[i],A[M[Point(p[i].x + 1,p[i].y)]],w[i]); if (M.count(Point(p[i].x,p[i].y - 1))) Add(B[i],A[M[Point(p[i].x,p[i].y - 1)]],w[i]); if (M.count(Point(p[i].x,p[i].y + 1))) Add(B[i],A[M[Point(p[i].x,p[i].y + 1)]],w[i]); } else if (p[i].x % 4 == 3 && !(p[i].y & 1)) { if (M.count(Point(p[i].x - 1,p[i].y))) Add(B[i],A[M[Point(p[i].x - 1,p[i].y)]],w[i]); if (M.count(Point(p[i].x,p[i].y - 1))) Add(B[i],A[M[Point(p[i].x,p[i].y - 1)]],w[i]); if (M.count(Point(p[i].x,p[i].y + 1))) Add(B[i],A[M[Point(p[i].x,p[i].y + 1)]],w[i]); } else if ((p[i].x % 4 == 2 && !(p[i].y & 1)) || (p[i].x % 4 == 3 && (p[i].y & 1))) Add(B[i],t,w[i]); } } inline bool BFS() { for (int i = 1; i <= t; i++) L[i] = 0; Q.push(s); L[s] = 1; while (!Q.empty()) { int k = Q.front(); Q.pop(); for (int i = 0; i < v[k].size(); i++) { E e = edgs[v[k][i]]; if (e.cap == e.flow || L[e.to]) continue; L[e.to] = L[k] + 1; Q.push(e.to); } } return L[t]; } inline int Dinic(int x,int a) { if (x == t) return a; int flow = 0; for (int &i = cur[x]; i < v[x].size(); i++) { E &e = edgs[v[x][i]]; if (e.cap == e.flow || L[e.to] != L[x] + 1) continue; int f = Dinic(e.to,min(e.cap - e.flow,a)); if (!f) continue; flow += f; e.flow += f; edgs[v[x][i]^1].flow -= f; a -= f; if (!a) return flow; } if (!flow) L[x] = -1; return flow; } int main() { #ifdef DMC freopen("DMC.txt","r",stdin); #endif C = getint(); R = getint(); n = getint(); for (int i = 1; i <= n; i++) { int x = getint(),y; y = getint(); w[i] = getint(); M[p[i] = Point(x,y)] = i; A[i] = ++tot; B[i] = ++tot; } s = ++tot; t = ++tot; Build(); int MinCut = 0; while (BFS()) { for (int i = 1; i <= t; i++) cur[i] = 0; MinCut += Dinic(s,INF); } cout << MinCut << endl; return 0; }