aa
查看原帖
aa
1486095
sunnybear楼主2025/8/30 18:46
#include<bits/stdc++.h>
#define int long long 
using namespace std;
struct node{
	int v,id;//a[u].id表示u<->v边的编号
};
const int N=5e5+5;
int n;
int dep[N];
int f[N][30];
vector<node> t[N];
int dan[N],duo[N];
int cf[N];//差分数组
int ans;
int eid[N];//eid[i]表示结点i到它父结点的边的编号
void dfs(int root,int fa){//预处理深度和fa数组
	f[root][0]=fa;
	dep[root]=dep[fa]+1;
	for(auto aaa:t[root]){
		int j=aaa.v;
		int i=aaa.id;
		if(j!=fa){
			eid[j]=i;
			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 aaa:t[u]){
		int j=aaa.v;
		if(j!=fa){
			fun(j,u);
			cf[u]+=cf[j];
		}
	}
	ans+=min(duo[eid[u]],dan[eid[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,i});
		t[v].push_back({u,i});
	}
	dfs(1,0);
	pre();
	for(int i=2;i<=n;i++){
		int c=LCA(i,i-1);
		cf[i]++;
		cf[i-1]++;
		cf[c]-=2;
	}
	fun(1,0);
	cout<<ans<<endl;
	return 0;
}
2025/8/30 18:46
加载中...