ZTL — 数据结构 — 最小割树

namespace NF{
	int last[maxn], dep[maxn], ecnt = 1;
	struct edge{int y, gg, w;} e[maxm<<2];
	inline void addedge(int x, int y, int w){
		e[++ecnt].y = y; e[ecnt].gg = last[x]; e[ecnt].w = w;
		last[x] = ecnt;
		e[++ecnt].y = x; e[ecnt].gg = last[y]; e[ecnt].w = 0;
		last[y] = ecnt;
	}
	inline bool bfs(int s, int t){
		memset(dep, 0, sizeof(dep));
		dep[s] = 1;
		queue<int> q; q.push(s);
		while(!q.empty()){
			int x = q.front(); q.pop();
			for(int i = last[x], y; i; i = e[i].gg){
				y = e[i].y;
				if(!dep[y] && e[i].w){
					dep[y] = dep[x]+1;
					q.push(y);
				}
			}
		}
		return (dep[t] != 0);
	}
	int dfs(int x, int t, int sum){
		if(x == t) return sum;
		int k, rest = sum;
		for(int i = last[x], y; i; i = e[i].gg){
			y = e[i].y;
			if(dep[y] == dep[x]+1 && e[i].w){
				k = dfs(y, t, min(rest, e[i].w));
				rest -= k; e[i].w -= k; e[i^1].w += k;
				if(k == 0) dep[y] = 0;
				if(rest == 0) break;
			}
		}
		return sum-rest;
	}
	int dicnic(int s, int t){
		for(int i = 2; i <= ecnt; i += 2){
			e[i].w = e[i].w+e[i^1].w;
			e[i^1].w = 0;
		}
		int ans = 0, now = 0;
		while(bfs(s,t)){
			while(now = dfs(s,t,inf)) ans += now;
		}
		return ans;
	}
}

namespace mct{
	int last[maxn], ecnt = 1;
	struct edge{int y, gg, w;} e[maxn<<1];
	inline void addedge(int x, int y, int w){
		e[++ecnt].y = y; e[ecnt].w = w; e[ecnt].gg = last[x];
		last[x] = ecnt;
	}

	int node[maxn];
	int g1[maxn], g2[maxn];
	void build(int l, int r){
		if(l == r) return;
		int s = node[l], t = node[l+1];;
		int cut = NF::dicnic(s,t);
		addedge(s,t,cut); addedge(t,s,cut);
		int n1 = 0, n2 = 0;
		for(int i = l; i <= r; ++i){
			if(NF::dep[node[i]]) g1[++n1] = node[i];
			else g2[++n2] = node[i];
		}
		for(int i = l; i <= l+n1-1; ++i) node[i] = g1[i-l+1];
		for(int i = l+n1; i <= r; ++i) node[i] = g2[i-n1-l+1];
		build(l, l+n1-1); build(l+n1, r);
	}

	int log2n, dep[maxn], anc[maxn][11], minl[maxn][11];
	void dfs(int x, int fa){
		dep[x] = dep[fa]+1;
		for(int i = 1; i <= log2n; ++i){
			anc[x][i] = anc[anc[x][i-1]][i-1];
			minl[x][i] = min(minl[x][i-1], minl[anc[x][i-1]][i-1]);
		}
		for(int i = last[x], y; i; i = e[i].gg){
			y = e[i].y;
			if(y == fa) continue;
			anc[y][0] = x;
			minl[y][0] = e[i].w;
			dfs(y,x);
		}
	}
	inline void preprocess(){
		log2n = log2(n)+1;
		for(int i = 1; i <= n; ++i) node[i] = i;
		build(1,n);
		dfs(1,0);
	}
	int query(int x, int y){
		int ans = inf;
		if(dep[x] < dep[y]) swap(x,y);
		for(int i = log2n; i >= 0; --i){
			if(dep[anc[x][i]] >= dep[y]){
				ans = min(ans, minl[x][i]);
				x = anc[x][i];
			}
		}
		if(x == y) return ans;
		for(int i = log2n; i >= 0; --i){
			if(anc[x][i] != anc[y][i]){
				ans = min(ans, min(minl[x][i], minl[y][i]));
				x = anc[x][i]; y = anc[y][i];
			}
		}
		ans = min(ans, min(minl[x][0], minl[y][0]));
		return ans;
	}
}

posted @ 2021-02-24 17:38  zimindaada  阅读(73)  评论(0编辑  收藏  举报