bzoj4519: [Cqoi2016]不同的最小割
留坑,谁能看出这代码为啥RE
5.3updated 知道了,因为col是bool,memset的时候n << 2 就不行了。。
#include<bits/stdc++.h> using namespace std; const int N = 850 + 10, M = 8500 + 10; bool col[N]; struct Dinic { struct Edge { int to, adv, cap; Edge *next; Edge() {} Edge(int to, int cap, Edge *next) : to(to), adv(cap), cap(cap), next(next) {} } pool[M * 2], *fir[N], *cur[N], *pis; Dinic() { pis = pool; } int s, t, n; void init(int s, int t, int n) { this->s = s, this->t = t, this->n = n; for(Edge *p = pool; p != pis; ++p) p->adv = p->cap; } void AddEdge(int u, int v, int w) { fir[u] = new(pis++) Edge(v, w, fir[u]); fir[v] = new(pis++) Edge(u, w, fir[v]); } int d[N]; bool BFS() { static int q[N], ql, qr; ql = qr = 0; memset(d, -1, n << 2); d[s] = 0, q[qr++] = s; while(ql < qr) { int u = q[ql++]; for(Edge *p = fir[u]; p; p = p->next) if(p->adv) { int v = p->to; if(d[v] == -1) { d[v] = d[u] + 1; q[qr++] = v; } } } return d[t] != -1; } #define inv(p) (pool + ((p - pool) ^ 1)) int DFS(int u, int a) { if(u == t || !a) return a; int flow = 0, f; for(Edge *&p = cur[u]; p; p = p->next) { int v = p->to; if(d[v] == d[u] + 1 && (f = DFS(v, min(p->adv, a))) > 0) { p->adv -= f; inv(p)->adv += f; flow += f; if(!(a -= f)) { break; } } } if(!flow) d[u] = -1; return flow; } int maxflow() { int flow = 0; while(BFS()) { memcpy(cur, fir, n << 2); flow += DFS(s, 1 << 29); } return flow; } void paint(int u) { col[u] = 1; for(Edge *p = fir[u]; p; p = p->next) if(p->adv) { int v = p->to; if(!col[v]) paint(v); } } } solver; map<int, int> vis; int id[N], n, ans; void solve(int l, int r) { if(l >= r) return; solver.init(id[l], id[r], n); if(!vis[solver.maxflow()]++) ans++; memset(col, 0, n << 2); solver.paint(id[l]); static int t1[N], t2[N]; int p1 = 0, p2 = 0; for(int i = l; i <= r; i++) { if(col[id[i]]) t1[p1++] = id[i]; else t2[p2++] = id[i]; } for(int i = 0; i < p1; i++) id[l + i] = t1[i]; for(int i = 0; i < p2; i++) id[l + p1 + i] = t2[i]; solve(l, l + p1 - 1); solve(l + p1, r); } int main() { int m; scanf("%d%d", &n, &m); for(int i = 0; i < m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); --u, --v; solver.AddEdge(u, v, w); } for(int i = 0; i < n; i++) id[i] = i; solve(0, n-1); printf("%d\n", ans); return 0; }
原文出处http://www.cnblogs.com/showson/