P1131 [ZJOI2007]时态同步(树的dfs回溯)

不难想到根到叶子节点的距离在调整后是固定的

一定是初始根到叶子节点距离的最大值

但是知道了又能怎么样呢??

d f s 很自然的想法是从根往下dfs

x , x 遍历到点x时,x子树中所有叶子节点到目根的距离分为两段

d i s [ ] = ( > x ) + ( x > ) dis[叶子节点]=(叶子节点->x)+(x->根)

> x 那么需要调整的就是叶子节点->x的边

x , 使 所以修改直接连接到x的边,使得所有叶子节点距离相同

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=5e5+10;
struct p{
	int to,w,nxt;
}d[maxn<<1]; int head[maxn<<1],cnt=1,ans;
void add(int u,int v,int w){
	d[cnt]=(p){v,w,head[u]}, head[u]=cnt++;
}
int a[maxn<<1],n,s,dis[maxn<<1];
void dfs(int u,int fa)
{
	for(int i=head[u];i;i=d[i].nxt)
	{
		int v=d[i].to;
		if( v==fa )	continue;
		dfs(v,u);
		dis[u]=max(dis[u],dis[v]+d[i].w);
	}
	for(int i=head[u];i;i=d[i].nxt)
	{
		int v=d[i].to;
		if( v==fa )	continue;
		ans+=( dis[u]-dis[v]-d[i].w );
	}
}
signed main()
{
	cin >> n >> s; 
	for(int i=1;i<n;i++)
	{
		int l,r,w;
		 cin >> l >> r >> w;
		 add(l,r,w); add(r,l,w);
	}
	dfs(s,0);
	cout << ans;
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107489220