您的位置:首页 > 其它

bzoj4519: [Cqoi2016]不同的最小割

2016-05-02 21:48 375 查看
留坑,谁能看出这代码为啥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
;

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
, *cur
, *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
;
bool BFS() {
static int q
, 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, 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
, t2
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: