树剖求调
查看原帖
树剖求调
326254
LonginusMonkey楼主2023/7/27 16:46

见了鬼了0pt

#include<bits/stdc++.h>
#define inf 2147483647
#define int long long
using namespace std;
struct node{
	int u, v, w;
}edge[50010];
struct Edge{
	int to, w;
};
vector<Edge> vec[50010];
int n, m;
bool cmp(node x, node y) {
	return x.w > y.w;
}
int fa[10010], vis[50010], tot;
int find(int index) {
	if(fa[index] == index) {
		return index;
	}
	return fa[index] = find(fa[index]);
}
int sonw[10010];
int top[10010], lenth[10010], size[10010], son[10010], new_w[10010], dfn[10010], depth[10010], father[10010], loc[10010];
void dfs1(int index, int back=0) {
	size[index] = 1;
	father[index] = back;
	vis[index] = 1;
	for(int i=0; i<vec[index].size(); ++i) {
		if(vec[index][i].to == back) continue;
		dfs1(vec[index][i].to, index);
		if(size[vec[index][i].to] > size[son[index]]) {
			son[index] = vec[index][i].to;
			sonw[index] = vec[index][i].w;
		}
		size[index] += size[vec[index][i].to];
	}
}
void dfs2(int index, int back, int tp) {
	dfn[index] = ++tot;
	depth[index] = depth[back] + 1;
	top[index] = tp;
	loc[index] = dfn[index];
	if(son[index])
	{
		dfs2(son[index], index, tp);
		new_w[dfn[son[index]]] = sonw[index];
	}
	for(int i=0; i<vec[index].size(); ++i) {
		if(vec[index][i].to == back || vec[index][i].to == son[index]) {
			continue;
		}
		dfs2(vec[index][i].to, index, vec[index][i].to);
		new_w[dfn[vec[index][i].to]] = vec[index][i].w;
	}
}
int tree[100100];
void build(int l, int r, int index){
	if(l==r) {
		tree[index] = new_w[l];
		return;
	}
	int mid = l + r >> 1;
	build(l, mid, index*2);
	build(mid+1, r, index*2+1); 
	tree[index] = min(tree[index*2], tree[index*2+1]);
}
int ask(int l, int r, int index, int left, int right) {
	if(left > right) return inf;
	if(l >= left && r <= right) {
		return tree[index];
	}
	if(l > right || r < left) {
		return inf;
	}
	int mid = l + r >> 1;
	return min(ask(l, mid, index*2, left, right), ask(mid+1, r, index*2+1, left, right));
}
int work(int left, int right) {
	int minn = inf;
	while(top[left] != top[right]) {
		if(depth[left] < depth[right]) {
			swap(left, right);
		}
		minn = min(minn, ask(1,n,1,dfn[top[left]],dfn[left]));
		left = father[top[left]];
	}
	if(depth[left] < depth[right]) {
		swap(left, right);
	}
//	cout <<"ask"<<ask(1,n,1,dfn[son[right]],dfn[left])<<endl;
//	cout <<"www"<<dfn[son[right]] << " " << dfn[left]<<endl;
	minn = min(minn, ask(1,n,1,dfn[son[right]],dfn[left]));
	return minn;
}
signed main() {
	ios::sync_with_stdio(0);cin.tie(0);
	memset(tree, 0x3f, sizeof tree);
	cin >> n >> m;
	for(int i=1; i<=n; ++i) {
		fa[i] = i;
	}
	for(int i=1; i<=m; ++i) {
		cin >> edge[i].u >> edge[i].v >> edge[i].w;
	}
	sort(edge+1, edge+1+m, cmp);
	for(int i=1; i<=m; ++i) {
		if(find(edge[i].u) != find(edge[i].v)) {
			fa[find(edge[i].u)] = find(edge[i].v);
			vis[i] = 1;
			++tot;
		}
		if(tot == n-1) {
			break;
		}
	}
	for(int i=1; i<=m; ++i) {
		if(vis[i]) {
			vec[edge[i].u].push_back({edge[i].v, edge[i].w});
			vec[edge[i].v].push_back({edge[i].u, edge[i].w});
		}
	}
	memset(vis, 0, sizeof vis);
	for(int i=1; i<=n; ++i) {
		if(!vis[i]) {
			dfs1(i);
		}
	}
	tot=0;
	for(int i=1; i<=n; ++i) {
		if(!dfn[i]) {
			dfs2(i, 0ll, i);
		}
	}
//	cout <<"debug"<<endl;
	build(1, n, 1);
	int q;
	cin >> q;
	while(q--) {
		int left, right;
		cin >> left >> right;
		if(find(left) != find(right)) {
			cout << -1 <<endl;
		}
		else
		{
			cout << work(left, right) << endl;
		}
	}
	return 0;
}
2023/7/27 16:46
加载中...