題目傳送門
題目大意:
看題面吧。
思考過程&具體做法:
很明顯我們無法直接求得全局的答案,所以要遞歸處理每棵子樹,用dp[i]代表使i的子樹中的所有葉子節點時態同步需要的最小代價,轉移方程爲dp[i]=
代碼:
#include <bits/stdc++.h>
using namespace std;
const long long maxn=5e5+100;
struct stu
{
long long to,next,dis;
}road[2*maxn]; long long first[maxn],cnt=0;
long long n,s;
long long dp[maxn],dis[maxn],fa[maxn];
void addedge(long long x,long long y,long long dis)
{
road[++cnt].to=y;
road[cnt].dis=dis;
road[cnt].next=first[x];
first[x]=cnt;
}
void dfs(long long now,long long dis1)
{
bool flag=0;
for(long long i=first[now];i;i=road[i].next)
{
long long to=road[i].to;
if(to==fa[now]) continue;
fa[to]=now;
flag=1;
dfs(to,dis1+road[i].dis);
dis[now]=max(dis[now],dis[to]);
dp[now]+=dp[to];
}
for(long long i=first[now];i;i=road[i].next)
{
long long to=road[i].to;
if(to==fa[now]) continue;
dp[now]+=(dis[now]-dis[to]);
}
if(!flag)
dis[now]=dis1;
}
int main()
{
scanf("%lld%lld",&n,&s);
for(long long i=1;i<=n-1;i++)
{
long long x,y,dis;
scanf("%lld%lld%lld",&x,&y,&dis);
addedge(x,y,dis);addedge(y,x,dis);
}
dfs(s,0);
printf("%lld\n",dp[s]);
return 0;
}