Sol-Dp-Dfs-时态同步

xiaoxiao2025-04-26  4

Solution of ZJOI2007-时态同步

树形Dp:

设: Dp[i]表示从第i个节点发出激励电流达到时态同步最少需要操作的次数

num[i]表示从第i个节点发出激励电流,Dp[i]最少时,从第i个节点到达叶子节点需要的时间最大值 ;

可得: n u m [ i ] = m a x { n u m [ j ] + e d g e ( i , j ) ∣ f a [ j ] = i } num[i] = max \{ num[j]+edge(i,j) |fa[j] = i \} num[i]=max{num[j]+edge(i,j)fa[j]=i} D p = ∑ j f a [ j ] = i    D p [ j ]    +    ∑ j f a [ j ] = i    n u m [ i ] − n u m [ j ] − e d g e ( i , j ) Dp = \sum_{j}^{fa[j]=i} \; Dp[j] \; + \; \sum_{j}^{fa[j]=i} \; num[i]-num[j]-edge(i,j) Dp=jfa[j]=iDp[j]+jfa[j]=inum[i]num[j]edge(i,j)

直接暴力转移即可,用类似Dfs的方法实现

demo:

#include<iostream> #include<cstdio> #include<algorithm> #define MAXN 500005 #define MAXM 500005 #define loop(X) for(int i = head[(X)] ; i ; i = Next[i]) using namespace std ; int edge[MAXM] , ver[MAXM] , Next[MAXM] , head[MAXN] , maxv[MAXN] ; int tot , N , S ; long long ans ; void add(int x,int y,int z){ edge[++tot] = z , ver[tot] = y , Next[tot] = head[x] ,head[x] = tot ; } void dfs(int x,int fa){ loop(x) if(ver[i] != fa) dfs(ver[i] , x) ; loop(x) if(ver[i] != fa) maxv[x] = max(maxv[x] , edge[i]) ; loop(x) if(ver[i] != fa) ans+=(maxv[x] - edge[i]) ; loop(fa) if(ver[i] == x) edge[i] += maxv[x] ; } int main(){ scanf("%d%d",&N,&S) ; for(int i = 1 ; i < N ; ++i){ int x , y , z ; scanf("%d%d%d",&x,&y,&z) ; add(x,y,z) , add(y,x,z) ; } dfs(S,0) ; printf("%lld\n",ans) ; }
转载请注明原文地址: https://www.6miu.com/read-5029179.html

最新回复(0)