Accumulation Degree -换根dp

因为这个换根比较简单,只简述一下要维护的东西:
1,每个节点维护一个weight[],表示从叶子到根的方向,这个点最多能接纳的流量。
2,边权。
所以画画图,手动模拟一下就得出了以下转移:

void dfs2(int u,int fa)
{
    
    
    for (int i = head[u]; i ; i = a[i].next) {
    
    
        int v = a[i].to;
        if (v == fa) continue;
        int now = res[u] - a[i].w;
        int c = 0;
        c += min(a[i].w,now);
        for (int j = head[v]; j ; j = a[j].next) {
    
    
            int vv = a[j].to;
            if (vv == u) continue;
            c += min(a[j].w,weight[vv]);
        }
//        cout << v << ' ' << c << endl;
        res[v] = c;
        dfs2(v,u);
    }
}

简单来说每个点的答案就是把当前节点v周围的流量重新再加起来。这个可以由weight[],边权,res[u]得出。
注意这里是顺推,因为下一个答案应有上一个答案得出。

//
// Created by SANZONG on 2021/7/8.
//
#include "bits/stdc++.h"
using namespace std;
const int maxn = 2e5;
struct node{
    
    
    int next,to,w;
}a[maxn<<1];
int cnt;
int head[maxn << 1];
void add(int u,int v,int w)
{
    
    
    a[++cnt].to = v;
    a[cnt].w = w;
    a[cnt].next = head[u];
    head[u] = cnt;
}

int weight[maxn];
void dfs(int u,int fa)
{
    
    
    if (a[head[u]].to == fa && !a[head[u]].next)
    {
    
    
        weight[u] = 0x3f3f3f3f;
        return;
    }
    int w = 0;
    for (int i = head[u]; i ; i = a[i].next) {
    
    
        int v = a[i].to;
        if (v == fa) continue;
        dfs(v,u);
        w += min(weight[v],a[i].w);
    }

    weight[u] = w;

}
int res[maxn];
void init()
{
    
    
    cnt = 0;
    memset(head,0,sizeof(head));
    memset(a,0,sizeof(a));
    memset(res,0,sizeof(res));
}

void dfs2(int u,int fa)
{
    
    
    for (int i = head[u]; i ; i = a[i].next) {
    
    
        int v = a[i].to;
        if (v == fa) continue;
        int now = res[u] - a[i].w;
        int c = 0;
        c += min(a[i].w,now);
        for (int j = head[v]; j ; j = a[j].next) {
    
    
            int vv = a[j].to;
            if (vv == u) continue;
            c += min(a[j].w,weight[vv]);
        }
//        cout << v << ' ' << c << endl;
        res[v] = c;
        dfs2(v,u);
    }
}
signed main()
{
    
    
//    freopen("in.txt","r",stdin);
    int T;
    cin >> T;
    while (T--)
    {
    
    
        init();
        int n;
        cin >> n;
        for (int i = 1; i <= n - 1; ++i) {
    
    
            int u,v,w;
            cin >> u >> v >> w;
            add(u,v,w);
            add(v,u,w);
        }
        int ans = 0;
        dfs(1,0);
        res[1] = weight[1];
        dfs2(1,0);
        for (int i = 1; i <= n; ++i) {
    
    
//            cout << i << ' ' << res[i] << endl;
            ans = max(ans,res[i]);
        }
        cout << ans << endl;
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_45509601/article/details/118574645
今日推荐