傳送門
小r的宿舍樓中有 n
nn 個地點和一些路,一條路連線了兩個地點,小r可以通過這條路從其中任意乙個地點到達另外乙個地點。但在剛開始,小r還不熟悉宿舍樓中的任何一條路,所以他會慢慢地發現這些路,他在發現一條路時還會知道這條路的溫度和長度。每條路的溫度都是互不相同的。
小r需要在宿舍樓中活動,每次他都需要從乙個地點到達另乙個地點。小r希望每次活動時經過一條最溫暖的路徑,最溫暖的路徑的定義為,將路徑上各條路的溫度從小到大排序後字典序最大。即溫度最低的路溫度盡量高,在滿足該條件的情況下,溫度第二低的路溫度盡量高,以此類推。小r不會經過重複的路。由於每條路的溫度互不相同,因此只存在一條最溫暖的路徑。
對於小r的每次活動,你需要求出小r需要走過的路徑總長度。如果小r通過當前發現的路不能完成這次活動,則輸出 −1-1
−1。注意本題中的字典序與傳統意義上的字典序定義有所不同,對於兩個序列 a,b
(a≠b
)a,b(a≠b)
a,b(a̸
=b)
,若 a
aa 是 b
bb 的字首則 a
aa 的字典序較大,同時可以推出空串的字典序最大。
輸入格式:
第一行兩個正整數 n,m
n,mn,
m。表示小r的宿舍樓中有 n
nn 個地點,共發生了 m
mm 個事件。
接下來 m
mm 行,每行描述乙個事件,事件分為三類。
find id u v t l:表示小r發現了一條連線 u
uu 和 v
vv 之間的路,編號為 idid
id。相同 idid
id的邊只會出現一次。
move u v:表示小r要從u
uu 到達 v
vv,你需要計算出最溫暖的路徑的長度 ,若不能從 u
uu 到達 v
vv,則輸出 −1-1
−1。change id l:表示從 u
uu 到 v
vv 這條邊的長度變為了 l
ll(保證在當前時間點這條邊存在)。
由於題目中要滿足溫度最低的路溫度盡量高,不難看出,這就是讓我們找最大瓶頸路。
那我們就得先找出圖中的最大生成樹(按照溫度)。
由於這是動態加邊,那麼很容易想到用 lct
\mathrm
lct 來維護最大生成樹。
然後對於每顆子樹,都維護一下溫度最小值和路徑之和。
詢問的時候,把 x
xx 和 y
yy 路徑單獨提取出來,詢問路徑之和即可。
#include
#include
#include
#include
#define n 500005
using
namespace std;
char op[10]
;int tem[n]
,len[n]
,e[n][2
];namespace lct
bool
isroot
(int x)
void
pushup
(int x)
void
pushdown
(int x)
void
rotate
(int x)
stack<
int>stk;
void
splay
(int x)
}void
access
(int x)
void
makeroot
(int x)
intfindroot
(int x)
void
split
(int x,
int y)
void
link
(int x,
int y)
void
cut(
int x,
int y)
}using
namespace lct;
intmain()
}}else
if(op[0]
=='m'
)else
}return0;
}
UOJ274 P6664 溫暖會指引我們前行
根據題目的條件 溫度各不相同 和要求 溫度排序後字典序最小 容易推出,實際上每次詢問就是要求兩個端點之間最低溫度最高的,同時不存在環 就是在最低溫最高基礎上最短 的一條路徑 其實和 水管局長 那題比較像,有連邊操作,想到用 lct 維護,對於每個新加入的邊 這樣做的正確性也就比較顯然,其實就是維護乙...
清華集訓 溫暖會指引我們前行
emmm其實我在uoj上過不去,加的資料我tle了。但是bzoj上還是可以的。關於push up的小trick 初始化的時候給0節點也初始化成最大值,然後push up的時候不用管自己的左右兒子是否為空,直接返回左右兒子中比較小的乙個就可以了,然後再和自己作比較。qwqwq 如下 include i...
BZOJ4736 溫暖會指引我們前行
給定n個點,要維護三種操作 find id u v t l 在u,v點間連一條編號id,溫度t,長度l的邊 保證溫度互不相同 move u v 詢問在u到v的路徑中,溫度從小到大排序後字典序最大的路徑的長度。若不存在路徑,輸出 1 change id l 將編號為id的邊長度改為l sample i...