現在開始正式填以前欠下的一些題解。就從這道經典的noip題開始講吧。
我們仔細看題目,發現要求的是圖上兩點\((u,v)\)之間的路徑上最小值的最大值。
跑dp?圖上狀態太多了,單次要\(o(n)\)的複雜度,直接t飛。
我們考慮一種經典方法:將圖轉化為一顆樹來做
由於樹保證聯通,而這裡要求最大化最小值,因此我們很容易想到把最大瓶頸生成樹找出來
然後在樹上維護資訊?那麼暴力樹剖維護最大值?複雜度雙\(log\)。有點危險。
再優化一波,我們用樹上倍增和維護倍增lca的方法一樣維護最大值,對於所有詢問的兩個點直接一起跳到它們的lca即可
注意圖可能不連通,不過我們前面的並查集就可以直接用來判連通性了。
code
#include#include#include#includeusing namespace std;
const int n=10005,p=15;
struct data
a[n*5];
int head[n],n,m,q,x,y,father[n],dep[n],par[n][p],f[n][p],cnt;
bool use[n];
struct edge
e[n<<1];
inline char tc(void)
inline void read(int &x)
inline void write(int x)
inline int getfather(int k)
inline bool cmp(data a,data b)
inline void double_add(int x,int y,int z)
inline int min(int a,int b)
return min(res,min(f[x][0],f[y][0]));
}int main()
while (q--)
return 0;
}
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 貨車運輸
a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入格式 輸入檔名為 truck.in。輸入檔案第一行有兩個用乙個空格隔開的整數 n,m,表示 ...
Luogu P1967 貨車運輸
p1967 貨車運輸 簡述題意 給定乙個圖,求兩點之間所有路徑上 最短邊最大的路一條路徑 的最短邊 突然繞 我應該表述複雜了 做法 最大生成樹 樹上倍增 先跑一遍最大生成樹。可以證明答案一定在最大生成樹上。建樹,樹上跑倍增 lca 取兩點路徑的 min 值就可以了w include include ...