Luogu P1967 NOIP2013 貨車運輸

2022-05-25 16:00:17 字數 1864 閱讀 6890

這個題是很經典的生成樹問題。第一次接觸時對倍增演算法的理解還不夠透徹,沒能打出來正解。

首先,原題中給出的是一幅圖,詢問從某點出發到另一點「需要經過的最短邊的最大值」。用floyd來解決是可以的,但是資料範圍不能承受o(n^3)的複雜度。於是我們考慮:假設原圖是連通的,那麼我們從某點到另一點,一定至少存在一條路徑;而明顯有一條路徑是最優的,滿足它所經過的最小邊最大。既然這樣,我們能不能把這條路徑找出來呢?於是我們想對原圖做一些處理。新的圖應該滿足:

1. 圖仍是連通的。

2. 任意兩點間的一條路徑滿足上述最優條件。

於是我們想到了生成樹。從貪心的角度考慮,兩點之間一定有一條這樣的最優路徑是最大生成樹上的唯一路徑。說明:因為最大生成樹外的一條邊一定小於等於樹上的邊權,那麼它不可能比這條樹上路徑更優。

求出mst後,我們要維護的是樹上路徑的最小值資訊。路徑本身可以用lca來搞,可是路徑上的資訊怎麼預處理呢?聯想st演算法,我們雖然不能維護任意兩點間的資訊,但是可以用倍增的思想,維護w(i, k)表示節點i到它的2^k代祖先所需經過的最短路徑。w(i, 0)就是生成樹上該點入邊的權,然後按k從小到大轉移,轉移方程w(i, k) = min(w(i, k - 1), w(f[i][k-1], k-1))。其中f陣列是按倍增法求lca記錄的祖先資訊。最後查詢時,所求的ans隨lca倍增演算法更新最小值即可。

注意原圖是不連通的,我們生成的實際上是乙個森林,kruscal演算法裡維護的並查集可以幫助判斷兩個點是否在乙個聯通塊內。

**:#include 

#include 

#include 

#include 

#include 

#define maxn 10010  

#define maxm 50010  

#define inf (int)2e9  

using namespace std;  

template    

void read(t &x)   

return;  

}  int n, m, q;  

int head[maxn], top = 1;  

struct e  edge[maxn << 1];  

struct pe  pedge[maxm];  

bool cmp(pe a, pe b)   

inline void insert(int u, int v, int w) ;  

head[u] = top;  

}  namespace ufs   

int find(int x)   

bool union(int u, int v)   

} using namespace ufs;  

void kruscal()   

}  }  

namespace lca   

}  void init2()   

for (int k = 1; k <= lg; ++k)  

for (int i = 1; i <= n; ++i)   

}  int query(int u, int v)   

return min(ans, min(w[0][u], w[0][v]));  

}  } using namespace lca;   

int main() ;  

}  kruscal();  

init2();  

read(q);  

while (q--)   

return 0;  

}  ps:看了這個題以後覺得樹剖貌似是個好東西,有空學習乙個。

(7.16)樹上路徑最小邊權用樹剖維護的確是很顯然的,之後可以打一下。

(8.2)今日乙份樹剖奉上,開啟我的暑假中二學習之旅。

luogu P1967 貨車運輸

題面傳送門 顯然不可以最長路。司機肯定喜歡走長的路徑,所以先把最大生成樹跑出來。然後再最大生成樹上跑倍增不就好了?實現 include include include define min a,b a b a b using namespace std int n,m,k,x,y,ans,flag ...

Luogu P1967 貨車運輸

現在開始正式填以前欠下的一些題解。就從這道經典的noip題開始講吧。我們仔細看題目,發現要求的是圖上兩點 u,v 之間的路徑上最小值的最大值。跑dp?圖上狀態太多了,單次要 o n 的複雜度,直接t飛。我們考慮一種經典方法 將圖轉化為一顆樹來做 由於樹保證聯通,而這裡要求最大化最小值,因此我們很容易...

luogu P1967 貨車運輸

a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入格式 輸入檔名為 truck.in。輸入檔案第一行有兩個用乙個空格隔開的整數 n,m,表示 ...