[Accumulation Degree]题解

Accumulation Degree

https://ac.nowcoder.com/acm/problem/51180

换根dp板子题,首先,我们要想想如果根为1时,1的答案

我们设表示以为根子树的中,若有无限流量,i点能往下流的最大流量。

我们不难推出式子

意义就是,我们知道一个儿子v可以向下流的最大流量是,我们最多可以向儿子v流的流量,所以我们最多向该儿子流的流量,所有儿子的这个值的和就是

特别的,若i是叶子的话,则

现在,考虑换根dp

现在,根据换根dp的套路,假设我们要把根换成的一个儿子

那么,我们画一个图:

现在我们要把根换成,图就变成了

注意到,我们设的dp是,关于的子树的,而在换根的过程中,只有的子树分别减少和增加了一个儿子,所以,我们只需要将x和y的dp值分别减少和增加变化的值即可将所有的dp值改成以y为根的dp值,即:

【注意,顺序不能反】

同样,我们再考虑下特殊的为叶子节点的情况

如果是叶子节点,那么图一定是这样:

我们发现,这个时候,的流量只能流向,所以对答案的贡献是,所以,我们只要把这个值和ans取max即可~【因为我们一开始,如果直接算的话会出错】

当然,我们注意到一定会将流量流向y,所以一定满足此时,所以我们直接把和ans取max即可

至此,我们就成功用将根x换成了它的一个儿子y,我们如果直接dfs一遍的话就可以求出以任意点为根(源点)时,整个树能流的最大流量,我们直接将答案和这些值取max即可

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+1;
#define int long long
struct node{
    int v,w,nex;
}t[N<<1];
int las[N],len;
int dp[N],ans;
bool flag[N];
inline void add(int u,int v,int w){
    t[++len]=(node){v,w,las[u]},las[u]=len;
}
inline void dfs1(int now,int fa){
    flag[now]=0;
    for(int i=las[now];i;i=t[i].nex){
        int v=t[i].v,w=t[i].w;
        if(v!=fa){
            flag[now]=1;
            dfs1(v,now);
            dp[now]+=min(dp[v],w);
        }
    }
    if(!flag[now]){
        dp[now]=2e9;
    }
}
inline void dfs2(int now,int fa){
    ans=max(ans,dp[now]);
    for(int i=las[now];i;i=t[i].nex){
        int v=t[i].v,w=t[i].w;
        if(v!=fa){
            int pas1=dp[now],pas2=dp[v];//偷懒,直接将原来的值存下来,dfs回来后直接改回去即可
            if(!flag[v]){
                ans=max(ans,w);
                continue;
            }
            dp[now]-=min(dp[v],w);dp[v]+=min(dp[now],w);
            dfs2(v,now);
            dp[now]=pas1,dp[v]=pas2;
        }
    }
}
signed main(){
    int T;
    scanf("%lld",&T);
    while(T--){
        memset(dp,0,sizeof(dp));
        memset(las,0,sizeof(las)),len=0;
        int n;ans=0;
        scanf("%lld",&n);
        for(int i=1;i<n;++i){
            int u,v,w;
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w),add(v,u,w);
        }
        dfs1(1,1);dfs2(1,1);
        printf("%lld\n",ans);
    }
    return 0;
}
全部评论

相关推荐

10-13 22:56
门头沟学院 C++
rt,鼠鼠的浪潮网签明天过期,鼠鼠是山东人,好像自己也能接受。之前的面试大厂基本挂干净了,剩下小米二面后在泡,问了下面试官没有挂,但要泡。还有海信似乎也通过了,不过在深圳,鼠鼠也不是很想去。其它还有一些公司应该陆陆续续还有一些面试,现在有些纠结是直接签了还是再等再面呢?大佬们能不能给鼠鼠提一些意见,万分感谢!!!
牛客78696106...:浪潮可不是开摆,当初我还是开发的时候我组长跟我说他们组有段时间天天1,2点走,早上5点就来,全组肝出来心肌炎,浪潮挣钱省立花可不是说说,当然也看部门,但是浪潮普遍就那dio样,而且你算下时薪就知道不高,没事也是9点半走,不然算你旷工
投递小米集团等公司10个岗位
点赞 评论 收藏
分享
09-13 17:25
亲切的00后在笔试:我也遇到了,所以我早他一步查看图片
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务