# 2485. Party (kamp)

Description Title
tree points $ n-$, $ n-1 $ edges after each edge takes a certain amount of time, any two points are Unicom.

There are $ K $ individuals ($ K $ distributed in different points) should be concentrated to a point a party.

Need a car from this point of departure gathering held after the meeting ended, this $ K $ individuals were sent back.

Please answer, for $ i = 1 \ cdots n $, if a party at the $ i $ th point, the driver how long it takes a minimum of $ K $ individuals to be sent home

数据范围
$ K \ N \ 500000.1 the \ the x, y \ N, 1 \ z \ le $ 1 million

Solution to a problem
if forced to go back, then, can be seen through the path twice, so the answer is the result of subtracting twice the path length of the longest chain

So considering DP $ $, $ F_i provided $ $ I $ denotes the starting point, and the subtree has completed its journey back, G_i $ $ $ I $ denotes the subtree, the key length from the point furthest possible violence against each point is the root $ dfs $, the final answer is $ f_ {root} -g_ {root} $

Dp formula can be listed:
$ F_i = \ + SUM f_v 2 \ {I W_ Times, V} $
$ G_i = max \ {{I W_ g_v +, V} \} $

Consider positive solutions, only $ dfs $ once and then change operation to root

Code

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=5e5+5,M=N<<1;
int n,k,t,sz[N],fl[N],hd[N],V[M],W[M],nx[M];
LL f[N],g[N],ans[N];
void add(int u,int v,int w){
    V[++t]=v;nx[t]=hd[u];hd[u]=t;W[t]=w;
}
void dfs(int x,int fr){
    sz[x]=fl[x];f[x]=g[x]=0;
    for (int i=hd[x];i;i=nx[i])
        if (V[i]!=fr){
            dfs(V[i],x);sz[x]+=sz[V[i]];
            if (sz[V[i]])
                f[x]+=f[V[i]]+2ll*W[i],
                g[x]=max(g[x],g[V[i]]+W[i]);
        }
}
void dp(int x,int fr,int w){
    ans[x]=f[x]-g[x];
    LL ax1=0,ax2=0;int id=0;
    for (int i=hd[x];i;i=nx[i])
        if (V[i]!=fr && sz[V[i]]){
            if (ax1<g[V[i]]+W[i])
                ax2=ax1,ax1=g[V[i]]+W[i],id=V[i];
            else ax2=max(ax2,g[V[i]]+W[i]);
        }
    if (sz[fr]){
        if (ax1<g[fr]+w)
            ax2=ax1,ax1=g[fr]+w,id=fr;
        else ax2=max(ax2,g[fr]+w);
    }
    for (int i=hd[x];i;i=nx[i])
        if (V[i]!=fr){
            if (sz[V[i]]){
                f[x]-=f[V[i]]+2ll*W[i];
                if (id==V[i]) g[x]=ax2;
                f[V[i]]+=f[x]+2ll*W[i];
                g[V[i]]=max(g[V[i]],g[x]+W[i]);
            }
            else f[V[i]]=f[x]+2ll*W[i],g[V[i]]=g[x]+W[i];
            sz[x]-=sz[V[i]];sz[V[i]]+=sz[x];dp(V[i],x,W[i]);
            sz[V[i]]-=sz[x];sz[x]+=sz[V[i]];
            if (sz[V[i]]){
                f[V[i]]-=f[x]+2ll*W[i];
                f[x]+=f[V[i]]+2ll*W[i];g[x]=ax1;
            }
        }
}
int main(){
    scanf("%d%d",&n,&k);
    for (int x,y,z,i=1;i<n;i++)
        scanf("%d%d%d",&x,&y,&z),
        add(x,y,z),add(y,x,z);
    for (int x,i=1;i<=k;i++)
        scanf("%d",&x),fl[x]=1;
    dfs(1,0),dp(1,0,0);
    for (int i=1;i<=n;i++)
        printf("%lld\n",ans[i]);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/xjqxjq/p/11317469.html