[luoguP1131] [ZJOI2007]时态同步(贪心)
显然是一棵树。
又显然一段一段地增加比较优。
我们可以dfs,并且尽量把每一个节点所有子树中所有节点的时间增加到一样。
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 500001
#define LL long long
using namespace std;
LL ans;
int n, s, cnt;
int head[N], to[N << 1], val[N << 1], nex[N << 1], dis[N];
bool vis[N];
vector <int> q[N];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
}
inline void add(int x, int y, int z)
{
to[cnt] = y;
val[cnt] = z;
nex[cnt] = head[x];
head[x] = cnt++;
}
inline void dfs(int u)
{
int i, v, t = -1;
vis[u] = 1;
for(i = head[u]; ~i; i = nex[i])
{
v = to[i];
if(!vis[v])
{
dis[v] = dis[u] + val[i];
dfs(v);
t = max(t, dis[v]);
q[u].push_back(dis[v]);
}
}
if(t > 0)
{
dis[u] = t;
for(i = 0; i < q[u].size(); i++) ans += t - q[u][i];
}
}
int main()
{
int i, x, y, z;
n = read();
s = read();
memset(head, -1, sizeof(head));
for(i = 1; i < n; i++)
{
x = read();
y = read();
z = read();
add(x, y, z);
add(y, x, z);
}
dfs(s);
printf("%lld\n", ans);
return 0;
}

浙公网安备 33010602011771号