码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4519: [Cqoi2016]不同的最小割

时间:2016-05-02 22:58:33      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:

留坑,谁能看出这代码为啥RE

#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;
}

 

bzoj4519: [Cqoi2016]不同的最小割

标签:

原文地址:http://www.cnblogs.com/showson/p/5453236.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!