Codeforces Round #847 F

F. Timofey and Black-White Tree

题链
因为是一棵树的形式 我们不妨考虑dp
dp[u]表示u节点子树内黑点离u的最近距离
我们每添加一个点 当然会更新他及他链上面父亲的dp值
显然要是我们当前跑上去的距离大于了上一次的答案 我们就可以不跑了
这样我们最坏的一种情况就是一条链的形式 并且每次拿大的出来二等分
每次要上去的点数就是 n n/2 n/2 n/4 n/4 n/4 n/4 8个n/8 16个n/16 。。。。
这样酷似调和级数 甚至还比调和级数小
我们考虑如何更新答案 其实答案就是ans每次和现在跑到的dp以及现在已经回朔的距离更新一下即可

int dp[N],rt,n,c[N],fa[N];
vector<int>g[N];
void dfs(int u,int p){
    for(auto v:g[u]){
        if(v==p)continue;
        dfs(v,u);
        fa[v]=u;
    }
}
void solve(){
    cin>>n>>rt;
    c[1]=rt;
    for(int i=0;i<=n;i++){
        g[i].clear();
        dp[i]=INF;
        fa[i]=0;
    }
    for(int i=2;i<=n;i++){
        cin>>c[i];
    }
    for(int i=1;i<n;i++){
        int u,v;cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(rt,0);
    int ans=INF;
    for(int i=1;i<=n;i++){
        int p=c[i],res=0;
        while(p>0&&ans>res){
            ans=min(ans,dp[p]+res);
            dp[p]=min(dp[p],res);
            p=fa[p];
            res++;
        }
        if(i!=1)cout<<ans<<' ';
    }cout<<endl;
}
posted @ 2023-01-28 15:19  ycllz  阅读(50)  评论(0)    收藏  举报