luogu P3994 高速公路

2021-09-16 12:17:08 字數 2513 閱讀 7338

逃了物理競賽,機房就2

22人。

有一棵樹,其中第i

ii個點到第j

jj個點的貢獻為dis

(i,j

)∗pi

+q

idis(i,j)*p_i+q_i

dis(i,

j)∗p

i​+q

i​.若i

ii是j

jj的祖先,則保證pi≤

pj

p_i≤p_j

pi​≤pj

​。顯然是乙個在樹上維護的斜率優化的dpdp

dp。對於一條根到葉子節點的路徑的路徑,它的斜率一定是單調的。那就好辦了,因為它們就可以放在一起維護了。而對於不在同一棵子樹內的兒子節點,回溯時注意單調佇列內的點被刪除的放回即可。

設f

if_i

fi​表示i

ii點到1

11號根節點的路徑的最小值。

則f i=

∑j∈i

.anc

esto

rfj+

pi∗d

is(i

,j)+

qi

f_i=\sum_

fi​=∑j

∈i.a

nces

tor​

fj​+

pi​∗

dis(

i,j)

+qi​

。由於i,j

i,ji,

j在同一條鏈上,因此dis

(i,j

)=di

s(i,

1)−d

is(j

−1

)dis(i,j)=dis(i,1)-dis(j-1)

dis(i,

j)=d

is(i

,1)−

dis(

j−1)

。設disi

=dis

1,

idis_i=dis_

disi​=

dis1

,i​,則:fi=

fj+∑

j.an

cest

orpi

(dis

i−di

sj)+

qi

f_i=f_j+\sum_

fi​=fj

​+∑j

.anc

esto

r​pi

​(di

si​−

disj

​)+q

i​。得到斜率方程:fj−

fkdi

sj−d

is

k

\fracdi

sj​−

disk

​fj​

−fk​

​​。套進去即可。

#include

#include

#include

#define ll long long

using

namespace std;

int n,m,len=

0,head,tail;

struct node a[

2000010];

int last[

1000010];

ll p[

1000010

],q[

1000010

],dis[

1000010

],f[

1000010];

int que[

1000010];

ll calc1

(int x,

int y)

ll calc2

(int x,

int y)

double

calc

(int x,

int y)

void

ins(

int x,

int y,

int z)

; last[x]

=len;

}int last_head[

1000010

],last_tail[

1000010

],tmp[

1000010

],pos[

1000010];

void

dfs(

int x,

int fa)

que[pos[x]

]=tmp[x]

; head=last_head[x]

,tail=last_tail[x];}

intmain()

head=1;

tail=0;

que[0]

=0;dfs(1

,0);

for(

int i=

2;i<=n;i++

)printf

("%lld\n"

,f[i]);

}

Luogu P3994 高速公路

c 國擁有一張四通八達的高速公路網樹,其中有 n 個城市,城市之間由一共 n 1 條高速公路連線。除了首都 1 號城市,每個城市都有一家本地的客運公司,可以發車前往全國各地,有若干條高速公路連向其他城市,這是乙個樹型結構,1 號城市 首都 為根。假設有乙個人要從 i 號城市坐車出發前往 j 號城市,...

ccf 高速公路

問題描述 某國有n個城市,為了使得城市間的交通更便利,該國國王打算在城市之間修一些高速公路,由於經費限制,國王打算第一階段先在部分城市之間修一些單向的高速公路。現在,大臣們幫國王擬了乙個修高速公路的計畫。看了計畫後,國王發現,有些城市之間可以通過高速公路直接 不經過其他城市 或間接 經過乙個或多個其...

201509 4 高速公路

鄰接表存圖 include include include define maxn 200010 using namespace std int dfn maxn low maxn int clock,top 當前元素是被訪問的序號,模擬棧的首部 bool instack maxn intstack...