題目大意
某市是乙個被分成h×w
h\times w
h×w塊區域的長方形,每個區域都是建築物、原野、牆壁之一。建築物的區域有p
pp個,編號為1…p
1\dots p
1…p。只有建築物和原野能夠進入,而且每次只能走到相鄰的區域中,且不能移動到市外。現在需要在各個建築物之間往返。在原野上每走過乙個區域都需要1
11單位的水。原野上不能提供水,但建築物裡有自來水可以將隨身攜帶的水壺裝滿。
給出該市的地圖和q
qq個詢問,對於第i
ii個詢問,輸出在建築物s
is_i
si和t
it_i
ti之間移動需要水壺的最小容積。
h ,w
⩽2000
h,w\leqslant 2000
h,w⩽20
00,p ,q
⩽2×1
05
p,q\leqslant 2\times 10^5
p,q⩽2×
105。
思路由於可以在建築物中補充水,從s
is_i
si走到t
it_i
ti可能會經過多個建築物,則需要水壺的最小容積為連續經過的兩個建築物之間的距離的最大值。要使路徑上的最大距離最小,可以想到最小生成樹。
如果以每個建築物為起點進行bfs,邊的數量就達到o(p
2)
o(p^2)
o(p2
),不可取。可以先把p
pp個建築物全部放入佇列中,同時向外擴充套件,用id[
i]
id[i]
id[i
]記下網格中區域i
ii最先被哪個建築物擴充套件到,dis
t[i]
dist[i]
dist[i
]記錄擴充套件的距離。然後討論相鄰的兩個區域i,j
i,ji,
j,將最先擴充套件到這兩個區域的建築物id[
i],i
d[j]
id[i],id[j]
id[i],
id[j
]之間連邊,邊長為dis
t[i]
+dis
t[j]
dist[i]+dist[j]
dist[i
]+di
st[j
],這樣邊的數量就減少到了o(h
w)
o(hw)
o(hw)。
少了這麼多邊,真的不會漏掉最小生成樹上的邊嗎?
假設最小生成樹上有一條邊連線建築物a,b
a,ba,
b:然後用kruskal求出生成樹,問題就變成了求樹上兩點間路徑上的最大邊權。預處理倍增陣列f[u
][i]
f[u][i]
f[u][i
],表示u
uu號點到fa[
u][i
]fa[u][i]
fa[u][
i]的路徑上的最大邊權,在求lca的時候順便統計答案。
另外本題求出的生成樹可能是森林,所以每棵樹都要dfs一遍求倍增陣列,還要判斷無解的情況。
bzoj 4242 水壺 最小生成樹 樹上倍增
為了降低ac率 這道題目我各種花樣作死爆oj,最後還是和標算改得差不多了。顯然答案應該為建築物構成的最小生成樹中,兩點間的最大路徑 那麼只要得到這棵最小生成樹就可以用倍增在o qlogn 的時間內得到答案了。因此關鍵是求最小生成樹。注意到是平面圖,因此考慮用bfs求最小生成樹。直接以每個建築為原點拓...
bzoj 題目選做
1.輪狀病毒 題目是很沒意思的 列出狀態 顯然無法遞推 我簡單推了一下加動態加點的狀態 嗯發現規律沒有那麼簡單 打表 也不太能發現吧 正解顯然是 矩陣樹定理啊 然後這題咕了 以後再複習矩陣樹定理的時候再證明這個結論吧 暫時當做打表做的。f n f n 3 f 2 然後高精加和高精減即可。由於都是高精...
BZOJ 3990 深搜思路題目
題目 小a有乙個1 2 n的排列a 1.2 n 他希望將a陣列從小到大排序,小a可以執行的操作有n種,每種操作最多可以執行一次,對於所有的i 1 i n 第i中操作為將序列從左到右劃分為2 段,每段恰好包括2 個數,然後整體交換其中兩段.小a想知道可以將陣列a從小到大排序的不同的操作序列有多少個,小...