洛谷P1131 [ZJOI2007]時態同步——題解

題目傳送門
題目大意:
看題面吧。


思考過程&具體做法:
很明顯我們無法直接求得全局的答案,所以要遞歸處理每棵子樹,用dp[i]代表使i的子樹中的所有葉子節點時態同步需要的最小代價,轉移方程爲dp[i]=dp[j]ji+


代碼:

#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;   
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章