bzoj1767[Ceoi2009]harbingers 斜率优化dp

1767: [Ceoi2009]harbingers

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 421  Solved: 112
[Submit][Status][Discuss]

Description

给定一颗树,树中每个结点有一个邮递员,每个邮递员要沿着唯一的路径走向capital(1号结点),每到一个城市他可以有两种选择: 1.继续走到下个城市 2.让这个城市的邮递员替他出发。 每个邮递员出发需要一个准备时间W[I],他们的速度是V[I],表示走一公里需要多少分钟。 现在要你求出每个城市的邮递员到capital的最少时间(不一定是他自己到capital,可以是别人帮他) N<=100000 3 ≤ N ≤ 100 000 0 ≤ Si≤ 10^9 1 ≤ Vi≤ 10^9 The length of each road will not exceed 10 000 For 20% of the tests, N ≤ 2 500 For 50% of the tests, each town will have at most 2 adjacent roads (i.e., the graph of roads will be a line)

Input

N 以下N-1行A,B,C三个数表示A,B之间有一条长为C的边。 再N行每行两数Wi,Vi 输出有一行N-1个数表示如题所述。

Output

Sample Input

5
1 2 20
2 3 12
2 4 1
4 5 3
26 9
1 10
500 2
2 30

Sample Output

206 321 542 328

HINT

比较裸的斜率优化
由于是一棵树,所以向儿子节点走的时候不能完全更改栈的信息(因为回到父亲节点的时候必须撤销儿子节点的操作)
为了节省时间,可以直接二分查找出需要修改的位置,记录当前栈的信息,修改后进入儿子,回来的时候复原即可
修改只修改一个位置并把栈顶重新设置为那个位置,否则会花费很多时间

这篇博客不错http://www.cnblogs.com/zj75211/p/8148736.html

 1 #include<bits/stdc++.h>
 2 #define N 100005
 3 #define ll long long
 4 using namespace std;
 5 ll dis[N],f[N];
 6 int n,tp,tot,s[N],hd[N],v[N],w[N];
 7 struct edge{int v,w,next;}e[N<<1];
 8 double g(int i,int j){
 9     return (double)(f[i]-f[j])/(double)(dis[i]-dis[j]);
10 }
11 void adde(int u,int v,int w){
12     e[++tot].v=v;
13     e[tot].w=w;
14     e[tot].next=hd[u];
15     hd[u]=tot;
16 }
17 int find(int l,int r,int x){
18     int mid=0;
19     while(l<=r){
20         mid=(l+r)>>1;
21         if(g(s[mid+1],s[mid])<v[x])l=mid+1;
22         else if(g(s[mid],s[mid-1])>v[x])r=mid-1;
23         else return mid;
24     }
25     return mid;
26 }
27 int insert(int l,int r,int u){
28     int mid=0;
29     while(l<=r){
30         mid=(l+r)>>1;
31         if(g(s[mid+1],s[mid])<g(u,s[mid]))l=mid+1;
32         else if(g(s[mid],s[mid-1])>g(s[mid],u))r=mid-1;
33         else return mid;
34     }
35     return mid;
36 }
37 void dfs(int u,int fa){
38     int pos=find(1,tp,u);
39     f[u]=f[s[pos]]+w[u]+v[u]*(dis[u]-dis[s[pos]]);
40     pos=insert(1,tp,u)+1;
41     int siz=tp,tmp=s[pos];
42     s[pos]=u;tp=pos;
43     for(int i=hd[u];i;i=e[i].next){
44         int v=e[i].v;
45         if(v==fa)continue;
46         dis[v]=dis[u]+e[i].w;
47         dfs(v,u);
48     }
49     s[pos]=tmp;tp=siz;
50 }
51
52 int main(){
53     scanf("%d",&n);
54     for(int i=1;i<n;i++){
55         int u,v,w;
56         scanf("%d%d%d",&u,&v,&w);
57         adde(u,v,w);adde(v,u,w);
58     }
59     for(int i=2;i<=n;i++)
60     scanf("%d%d",&w[i],&v[i]);
61     dfs(1,0);
62     for(int i=2;i<=n;i++){
63         printf("%lld",f[i]);
64         if(i!=n)putchar(‘ ‘);
65     }
66     return 0;
67 }

原文地址:https://www.cnblogs.com/wsy01/p/8168591.html

时间: 2024-10-11 08:23:24

bzoj1767[Ceoi2009]harbingers 斜率优化dp的相关文章

bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小. 帮助Pine求出最小方差是多少. 设方差是v,可以证明,v×m^2是一个整数.为了避免精度误差,输出结果时输出v×m^2. In

[bzoj 1911][Apio 2010]特别行动队(斜率优化DP)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1911 分析: 首先可以的到裸的方程f[i]=max{f[j]+a*(Si-Sj)^2+b*(Si-Sj)+c} 0<j<i 简化一下方程,我们知道对于一次项,最后结果肯定是b*Sn 所以可以写成f[i]=max{f[j]+a*(Si-Sj)^2+c} 0<j<i 我们不妨设0<x<y<i,且x比y优 即f[x]+a*(Si-Sx)^2+c>f[y]+a*

hdu 2993 MAX Average Problem (斜率优化dp入门)

MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5855    Accepted Submission(s): 1456 Problem Description Consider a simple sequence which only contains positive integers as

hdu3507之斜率优化DP入门

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 4780    Accepted Submission(s): 1437 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu

bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏.由于地形的不同,在不同工厂建立仓库的费用可能是不同的.第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci.对

HDU3045 Picnic Cows(斜率优化DP)

Picnic Cows Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2192    Accepted Submission(s): 675 Problem Description It’s summer vocation now. After tedious milking, cows are tired and wish to t

BZOJ 1096 [ZJOI2007]仓库建设 斜率优化dp

1096: [ZJOI2007]仓库建设 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=1096 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚. 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场

HDU 2829 Lawrence (斜率优化DP或四边形不等式优化DP)

题意:给定 n 个数,要你将其分成m + 1组,要求每组数必须是连续的而且要求得到的价值最小.一组数的价值定义为该组内任意两个数乘积之和,如果某组中仅有一个数,那么该组数的价值为0. 析:DP状态方程很容易想出来,dp[i][j] 表示前 j 个数分成 i 组.但是复杂度是三次方的,肯定会超时,就要对其进行优化. 有两种方式,一种是斜率对其进行优化,是一个很简单的斜率优化 dp[i][j] = min{dp[i-1][k] - w[k] + sum[k]*sum[k] - sum[k]*sum[

BZOJ 3156: 防御准备 斜率优化DP

3156: 防御准备 Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战线花费值. Sample Input 10 2 3 1 5 4 5 6 3 1 2 Sample Output 18 HINT 1<=N<=10^6,1<=Ai<=10^9 题解: 斜率优化DP: 首先将数组倒置 设定dp[i] 为前i的点的最优答案 易得 dp[i] = min{dp[j