1. 程式人生 > >【洛谷P1131】時態同步

【洛谷P1131】時態同步

ios main mes code str name dfs == span

做這個題還是比較順手的,起碼做起來挺舒服的。他讓我們求使所有葉子節點到根節點距離一樣的代價,那麽作為一顆子樹來說首先就要滿足這點,因為再往上走的路徑都是一樣的,因此我們需要先求所有子樹的最大深度,然後答案=(子樹最大深度-子樹蛾子子樹最大深度-子樹到其蛾子的距離+修改蛾子子樹的代價)

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
long long dp[500050],shu[500050];
int n,roo,tail,x,y,z,head[500050];
struct in { int to,ne,co; }ter[1000010]; inline void build(int f,int l,int c) { ter[++tail]=(in){l,head[f],c},head[f]=tail; ter[++tail]=(in){f,head[l],c},head[l]=tail; } void dfs(int ro,int fa) { if(head[ro]==-1)//如果發現當前這個點沒有蛾子,說明這是葉子節點,返回 return; for(int i=head[ro];i!=-1
;i=ter[i].ne) { int t=ter[i].to; if(t==fa) continue; dfs(t,ro); shu[ro]=max(shu[ro],shu[t]+ter[i].co);//先求出最大深度 } for(int i=head[ro];i!=-1;i=ter[i].ne) { int t=ter[i].to; if(t==fa) continue; dp[ro]
+=shu[ro]-shu[t]-ter[i].co+dp[t];//答案取決於深度差於修改值之和 } } int main() { scanf("%d%d",&n,&roo); memset(head,-1,sizeof(head)); for(int i=1;i<=n-1;i++) scanf("%d%d%d",&x,&y,&z),build(x,y,z);//建圖 dfs(roo,0); printf("%lld",dp[roo]); }

【洛谷P1131】時態同步