其他分享
首页 > 其他分享> > 洛谷3647:连珠线

洛谷3647:连珠线

作者:互联网

洛谷3647:连珠线

题意描述:

思路:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;

int head[maxn], nex[maxn<<1], edge[maxn<<1], ver[maxn<<1], tot;
inline void add_edge(int x, int y, int z){
    ver[++tot] = y; edge[tot] = z;
    nex[tot] = head[x]; head[x] = tot;
}

int n;
int fa[maxn], len[maxn], ans = -INF;
int f[maxn][3];
vector<int> son[maxn], dp[maxn][2], maxx[maxn];

void dfs(int x, int ff)
{
    f[x][0] = 0;
    f[x][1] = -INF;
    int mx1, mx2; mx1 = mx2 = -INF; //记录最大值与次大值
    for(int i = head[x]; i; i = nex[i])
    {
        int y = ver[i], z = edge[i];
        if(y == ff) continue;
        fa[y] = x; len[y] = z;
        son[x].push_back(y);
        dfs(y, x);
        f[x][0] += max(f[y][0], f[y][1] + z);
        int pre = f[y][0] + z - max(f[y][0], f[y][1]+z);
        if(pre > mx1) mx2 = mx1, mx1 = pre;
        else if(pre > mx2) mx2 = pre;
    }
    f[x][1] = f[x][0] + mx1;

    for(int i = head[x]; i; i = nex[i])
    {
        int y = ver[i], z = edge[i];
        if(y == ff) continue;
        dp[x][0].push_back(f[x][0]-max(f[y][0], f[y][1]+z));
        int pre = f[y][0] + z - max(f[y][0], f[y][1]+z);
        if(mx1 == pre) maxx[x].push_back(mx2), dp[x][1].push_back(mx2 + dp[x][0].back());
        else maxx[x].push_back(mx1), dp[x][1].push_back(mx1 + dp[x][0].back());
    }
}

void solve(int x)
{
    for(int i = 0; i < (int)son[x].size(); i++)
    {
        //换根
        f[x][1] = dp[x][1][i], f[x][0] = dp[x][0][i];
        if(fa[x]) 
        {
            int y = fa[x];
            f[x][0] += max(f[y][0], f[y][1]+len[x]); //加上父亲的贡献
            f[x][1] = f[x][0] + max(maxx[x][i], f[y][0]+len[x]-max(f[y][0], f[y][1]+len[x]));
        }
        ans = max(ans, f[son[x][i]][0] + max(f[x][0], f[x][1]+len[son[x][i]]));
        solve(son[x][i]);
    }
}

int main()
{
    scanf("%d", &n);
    for(int i = 1, x, y, z; i++ <= n - 1;)
    {
        scanf("%d%d%d", &x, &y, &z);
        add_edge(x, y, z); add_edge(y, x, z);
    }
    dfs(1, 0); solve(1);
    cout << ans << endl;
    return 0;
}

标签:洛谷,int,max,蓝线,son,连珠,3647,mx1,dp
来源: https://www.cnblogs.com/zxytxdy/p/12189051.html