luogu1967 貨車運輸

2021-08-03 20:14:44 字數 1964 閱讀 8682

題目描述

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;}

luogu 1967 貨車運輸

題目大意 無向圖上 每次詢問兩個點 尋找一條路徑使這條路徑上的最小值最大 思路 先跑乙個最大生成樹 然後在最大生成樹上每次對每兩個點跑乙個lca 在倍增的同時開乙個陣列a i j 記錄從i個點往上跑j條路裡j條路中的最小值 然後每次lca的時候順便記錄一下就行了 1 include2 include...

luogu1967 貨車運輸

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

luogu1967 貨車運輸

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