传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3677

http://uoj.ac/problem/105

【题解】

我们发现这样一个结论:如果把某个点作为根,那么蓝线一定是fa-x-son这种情况。

而且一个点作为只能作为一条蓝线的中点。

那么可以dp:

令f[i][0/1]表示x是否为蓝线中点的max值。

bzoj3677 [Apio2014]连珠线

具体解释:

1. i不是蓝线中点:那么可能从下面的所有蓝线中点连接上来取个max即可。

2. i是蓝线中点:那么我们去掉一个连接的点,把它改为连线(就是连一条son->i的蓝线),那么i就是蓝线中点了。

那么我们对每个根做一个dp,就是O(n^2)的,可以有50多分?

# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 2e5 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

int n;
int head[M], nxt[M], to[M], w[M], tot=0;
inline void add(int u, int v, int _w) {
    ++tot; nxt[tot] = head[u]; head[u] = tot;
    to[tot] = v; w[tot] = _w;
}
inline void adde(int u, int v, int _w) {
    add(u, v, _w); add(v, u, _w);
}

ll f[M][2], ans;

inline void dfs(int x, int fa) {
    f[x][0] = 0, f[x][1] = -1e18;
    for (int i=head[x]; i; i=nxt[i]) {
        if(to[i] == fa) continue;
        dfs(to[i], x);
        f[x][0] += max(f[to[i]][0], f[to[i]][1] + w[i]);
        f[x][1] = max(f[x][1], -max(f[to[i]][0], f[to[i]][1] + w[i]) + f[to[i]][0] + w[i]);
    }
    f[x][1] += f[x][0];
}

int main() {
    scanf("%d", &n);
    for (int i=1, u, v, _w; i<n; ++i) {
        scanf("%d%d%d", &u, &v, &_w);
        adde(u, v, _w);
    }
    for (int i=1; i<=n; ++i) {
        dfs(i, 0);
        ans = max(ans, f[i][0]);
    }
    printf("%lld\n", ans);
    return 0;
}
View Code

相关文章:

  • 2021-07-10
  • 2021-09-28
  • 2021-11-20
  • 2022-02-20
  • 2021-12-14
  • 2021-07-14
  • 2021-07-04
  • 2022-12-23
猜你喜欢
  • 2021-09-13
  • 2022-12-23
  • 2021-08-08
  • 2021-10-21
  • 2022-01-28
  • 2021-12-05
  • 2021-12-30
相关资源
相似解决方案