P1131 [ZJOI2007] 时态同步

给一颗树,带边权,树根是 \(S\)。每次可以给一条边权 \(+1\) 并花费 \(1\) 的代价,求最小代价使得 \(S\) 到所有叶子距离相等。
明显对于任意一个子树都满足到所有叶子距离相等。
所以就开始树形 dp:\(dp_i\)\(i\) 子树的最小操作次数。\(g_i\) 是这个点到其子树叶节点的距离。
因为边权只增不减,所以 \(g_i=\max(g_j)+w(i,j)\)。然后 dp 就是从子树转移过来的,和边权需要加上的:\(dp_i=\sum (dp_j)+\sum(g_i-g_j)\)

#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int> > e[500005];
long long f[500005],g[500005];
int n,s;
void dfs(int u,int fa){
	if(e[u].size()==1&&u!=s)return ;
	long long maxx=0;
	for(auto E:e[u]){
		int v=E.first,w=E.second;
		if(v==fa)continue;
		dfs(v,u);
		maxx=max(g[v]+w,maxx);
	}
	g[u]=maxx;
	for(auto E:e[u]){
		int v=E.first,w=E.second;
		if(v==fa)continue;
		f[u]+=(maxx-(g[v]+w))+f[v];
	}
   // cout<<u<<" "<<g[u]<<" "<<f[u]<<endl;
}
int main(){
	cin>>n>>s;
	for(int i=1;i<n;i++){
		int x,y,w;
		cin>>x>>y>>w;
		e[x].push_back(make_pair(y,w));
		e[y].push_back(make_pair(x,w));
	}
	dfs(s,0);
	cout<<f[s];
	return 0;
}

P1131 [ZJOI2007] 时态同步

上一篇:路由器的结构


下一篇:maven的settings配置