[Bzoj1767][Ceoi2009]harbingers (树上斜率优化)

Posted zcr-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Bzoj1767][Ceoi2009]harbingers (树上斜率优化)相关的知识,希望对你有一定的参考价值。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
struct node{
	int pre, to, val;
}edge[MAXN << 1];
int n, head[MAXN], tot, fa[MAXN], stk[MAXN], top, pos[MAXN];
ll W[MAXN], V[MAXN], dp[MAXN], dis[MAXN];
void add_edge(int u, int v, int l) {
	edge[++tot] = node{head[u], v, l};
	head[u] = tot;
}
double slope(int i, int j) {
	if (dis[i] == dis[j]) return 1e18;
	return 1.0 * (dp[i] - dp[j]) / (dis[i] - dis[j]);
}
void dfs(int x) {
	if (x != 1) {
		//二分统计答案 
		int l = 1, r = top - 1, now = top;
		while (l <= r) {
			int mid = (l + r) >> 1;
			if (slope(stk[mid], stk[mid + 1]) > V[x]) now = mid, r = mid - 1;
			else l = mid + 1;
		}
		dp[x] = dp[stk[now]] - V[x] * dis[stk[now]] + W[x] + dis[x] * V[x]; 
	}
	bool flag = true;
	int tmp, temp;
	pos[x] = top;//pos记录每个点加进去之前的栈到哪个位置 
	if (top == 0) {//如果当前栈里没有点 
		stk[++top] = x;
	} else {
		int l = 2, r = top, now = 1;
		while (l <= r) {
			int mid = (l + r) >> 1;
			if (slope(stk[mid - 1], stk[mid]) < slope(stk[mid - 1], x)) now = mid, l = mid + 1; 
			else r = mid - 1;
		}
		flag = false;
		tmp = stk[now + 1];
		stk[now + 1] = x;
		top = now + 1;
		temp = now;
	}
	for (int i = head[x]; i; i = edge[i].pre) {
		int y = edge[i].to;
		if (y == fa[x]) continue;
		fa[y] = x;
		dis[y] = dis[x] + edge[i].val;
		dfs(y);
	}
	top = pos[x];
	if (!flag) stk[temp + 1] = tmp;
}
int main() {
	memset(dp, 0x3f, sizeof(dp));
	scanf("%d", &n);
	for (int i = 1; i < n; i++) {
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		add_edge(a, b, c);
		add_edge(b, a, c);
	}
	for (int i = 2; i <= n; i++) scanf("%lld%lld", &W[i], &V[i]);
	dp[1] = 0;
	dfs(1);
	for (int i = 2; i <= n; i++) printf("%lld ", dp[i]);
	return 0;
}

以上是关于[Bzoj1767][Ceoi2009]harbingers (树上斜率优化)的主要内容,如果未能解决你的问题,请参考以下文章

[Bzoj1767][Ceoi2009]harbingers (树上斜率优化)

bzoj 1767: [Ceoi2009]harbingers

●BZOJ 3672 [Noi2014]购票

BZOJ——T 1800: [Ahoi2009]fly 飞行棋

BZOJ 1391: [Ceoi2008]order [最小割]

BZOJ4356 : Ceoi2014 Wall