過路費(最小生成樹 lca)

2022-03-14 10:22:27 字數 1842 閱讀 5559

題目描述:

在某個遙遠的國家裡,有 n個城市。編號為 1,2,3,…,n。這個國家的**修建了m 條雙向道路,每條道路連線著兩個城市。**規定從城市 s 到城市t需要收取的過路費為所經過城市之間道路長度的最大值。如:a到b長度為 2,b到c 長度為3,那麼開車從 a經過 b到c 需要上交的過路費為 3。

佳佳是個做生意的人,需要經常開車從任意乙個城市到另外乙個城市,因此他需要頻繁地上交過路費,由於忙於做生意,所以他無時間來尋找交過路費最低的行駛路線。然而, 當他交的過路費越多他的心情就變得越糟糕。 作為秘書的你,需要每次根據老闆的起止城市,提供給他從開始城市到達目的城市,最少需要上交多少過路費。

輸入描述:

第一行是兩個整數 n 和m,分別表示城市的個數以及道路的條數。

接下來 m 行,每行包含三個整數 a,b,w(1≤a,b≤n,0≤w≤10^9),表示a與b之間有一條長度為 w的道路。

接著有一行為乙個整數 q,表示佳佳發出的詢問個數。

再接下來 q行,每一行包含兩個整數 s,t(1≤s,t≤n,s≠t), 表示開始城市s 和目的城市t。

輸出描述:

輸出共q行,每行乙個整數,分別表示每個詢問需要上交的最少過路費用。輸入資料保證所有的城市都是連通的。

樣例輸入:

4 5

1 2 10

1 3 20

1 4 100

2 4 30

3 4 10

2 1 4

4 1

樣例輸出:

對於 30%的資料,滿足 1≤ n≤1000,1≤m≤10000,1≤q≤100;

對於 50%的資料,滿足 1≤ n≤10000,1≤m≤10000,1≤q≤10000;

對於 100%的資料,滿足 1≤ n≤10000,1≤m≤100000,1≤q≤10000;

思路:

在最小中求最大,

先跑一邊最小生成樹,找出最小。

在樹上跑lca找最大。

這道題和「火車運輸」為同一類題

#include

#include

#include

using

namespace

std;

const

int maxn=100010;

int n,m,tot,head[maxn];

int father[maxn],deep[maxn],f[maxn][20],dis[maxn][20];

struct node

e[maxn*2];

struct edge

}a[maxn];

void add_edge(int u,int v,int w)

int lca(int a,int b)

d>>=1;}}

if(a==b)

return ans;

for(int i=19;i>=0;i--)

if(f[a][i]!=f[b][i])

ans=max(ans,max(dis[a][0],dis[b][0]));

return ans;

}void init()

}void build(int u)

}int find(int x)

void kruskal()

if(tot==m-1) break;

}}int main()

return

0;}

codevs1519 過路費 最小生成樹 LCA

時間限制 1 s 空間限制 256000 kb 題目等級 大師 master 在某個遙遠的國家裡,有 n個城市。編號為 1,2,3,n。這個國家的 修建了m 條雙向道路,每條道路連線著兩個城市。規定從城市 s 到城市t需要收取的過路費為所經過城市之間道路長度的最大值。如 a到b長度為 2,b到c 長...

fzu 2082 過路費(樹鏈剖分)

思路 樹鏈剖分的裸題了 include include include include define ll long long using namespace std const int maxn 50000 100 int siz maxn fa maxn son maxn dep maxn to...

解題報告 FZU 2082 過路費 樹剖

比較裸的樹剖,但是給的是邊權,這時候就要把每條邊的邊權下放到深度相對更深的點中。然後正常樹剖操作。單點修改就改對應邊深度深的那個點的點權,區間查詢需要判斷下 首先還是正常重邊上查詢,然後最後兩點在同一條重邊後,如果這兩個點相同的話就不用再查詢這個點的點權了,因為我們要看的實際是邊,如果不同就要少算那...