0pts求调
查看原帖
0pts求调
1486095
sunnybear楼主2025/8/30 09:48
#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=5e5+5;
int n;
int dep[N];
int f[N][30];
vector<int> t[N];
int dan[N],duo[N];
int cf[N];//差分数组
int ans;
void dfs(int root,int fa){//预处理深度和fa数组
	f[root][0]=fa;
	dep[root]=dep[fa]+1;
	for(int j:t[root]){
		if(j!=fa){
			dfs(j,root);
		}
	}
}
void pre(){
	for(int i=1;i<=20;i++){
		for(int p=1;p<=n;p++){
			f[p][i]=f[f[p][i-1]][i-1];
		}
	}
}
int LCA(int u,int v){
	if(dep[u]<dep[v]) swap(u,v);
	for(int i=20;i>=0;i--){
		if(dep[u]-dep[v]>=(1 << i))
			u=f[u][i];
	}
	if(u==v) return u;
	for(int i=20;i>=0;i--){
		if(f[u][i]!=f[v][i]){
			u=f[u][i];
			v=f[v][i];
		}
	}
	return f[u][0];
}
void fun(int u,int fa){//树上前缀和统计答案
	for(auto v:t[u]){
		if(v!=fa){
			fun(v,u);
			cf[u]+=cf[v];
		}
	}
	ans+=min(duo[u],dan[u]*cf[u]);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v>>dan[i]>>duo[i];
		t[u].push_back(v);
		t[v].push_back(u);
	}
	pre();
	dfs(1,0);
	for(int i=1;i<=n-1;i++){
		int c=LCA(i,i+1);
		cf[i]++;
		cf[i+1]++;
		cf[c]--;
		cf[f[c][0]]--;
	}
	fun(1,0);
	cout<<ans<<endl;
	return 0;
}
2025/8/30 09:48
加载中...