題目描述
a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物, 司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。
輸入輸出格式
輸入格式:
輸入檔名為 truck.in。
輸入檔案第一行有兩個用乙個空格隔開的整數 n,m,表示 a 國有 n 座城市和 m 條道
路。 接下來 m 行每行 3 個整數 x、 y、 z,每兩個整數之間用乙個空格隔開,表示從 x 號城市到 y 號城市有一條限重為 z 的道路。注意: x 不等於 y,兩座城市之間可能有多條道路 。
接下來一行有乙個整數 q,表示有 q 輛貨車需要運貨。
接下來 q 行,每行兩個整數 x、y,之間用乙個空格隔開,表示一輛貨車需要從 x 城市運輸貨物到 y 城市,注意: x 不等於 y 。
輸出格式:
輸出檔名為 truck.out。
輸出共有 q 行,每行乙個整數,表示對於每一輛貨車,它的最大載重是多少。如果貨
車不能到達目的地,輸出-1。
輸入輸出樣例
輸入樣例#1:
4 3
1 2 4
2 3 3
3 1 1
3 1 3
1 4
1 3輸出樣例#1:
3 -1
3分析:
這道題說白了就是使兩點之間所有路徑中的最小路徑權值最大
首先我們考慮到,如果直接連通的兩點之間都多條路徑,我們肯定首選權值最大的那一條,
因此我們可以把整個圖簡化一下,選中一些權值很大的邊,
把無用的邊(也就是可以等效替換掉的)刪掉,選盡量少的邊
這些邊可以聯通所有點,而且權值最大,
這不就是最大生成樹嗎。。。
於是我們把一幅圖轉化成了一棵樹,
現在的問題就是怎樣求樹上兩點之間的路徑中的最小值,
秒想:樹鏈剖分
然而樹鏈剖分又臭又長,常數還大
所以我們選擇一種更為優越的寫法:樹上倍增
建立兩個陣列,乙個記錄該節點向上跳2^i步的爸爸
乙個記錄該節點向上跳2^i步經過的路徑的最小值
這樣在每次詢問的時候進行一次類似lca的查詢就ok了
這裡寫**片
#include
#include
#include
#include
#include
using
namespace
std;
const
int n=10001;
struct node;
node wy[n*5];
struct node1;
node1 way[n<<1];
int n,m,q,st[n],tot=0;
int ba[n],mn[n][20],f[n][20],deep[n];
int un,de=0;
int cmp(const node &a,const node &b)
void add(int u,int w,int z)
void unionn(int r1,int r2)
int find(int a)
void doit()
}}void dfs(int now,int dep,int faa)
}void cl()
}int ask(int u,int w)
if (u==w) return ans;
for (i=un;i>=0;i--)
if (f[u][i]!=f[w][i])
ans=min(ans,mn[u][0]);
ans=min(ans,mn[w][0]);
return ans;
}int main()
return
0;}
luogu1967 貨車運輸
題目描述 a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入輸出格式 輸入格式 輸入檔名為 truck.in。輸入檔案第一行有兩個用乙個空格隔...
luogu 1967 貨車運輸
題目大意 無向圖上 每次詢問兩個點 尋找一條路徑使這條路徑上的最小值最大 思路 先跑乙個最大生成樹 然後在最大生成樹上每次對每兩個點跑乙個lca 在倍增的同時開乙個陣列a i j 記錄從i個點往上跑j條路裡j條路中的最小值 然後每次lca的時候順便記錄一下就行了 1 include2 include...
luogu1967 貨車運輸
題目描述 a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入輸出格式 輸入格式 輸入檔名為 truck.in。輸入檔案第一行有兩個用乙個空格隔...