P1967 貨車運輸 LCA 生成樹

2022-05-18 05:53:36 字數 3070 閱讀 5357

a 國有 nn 座城市,編號從 11 到 nn,城市之間有 mm 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。

現在有 qq 輛貨車在運輸貨物, 司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。

第一行有兩個用乙個空格隔開的整數 n,mn,m,表示 aa 國有 nn 座城市和 mm 條道路。

接下來 mm 行每行三個整數 x, y, zx,y,z,每兩個整數之間用乙個空格隔開,表示從 xx 號城市到 yy 號城市有一條限重為 zz 的道路。

注意: x \neq yx​=y,兩座城市之間可能有多條道路 。

接下來一行有乙個整數 qq,表示有 qq 輛貨車需要運貨。

接下來 qq 行,每行兩個整數 x,yx,y,之間用乙個空格隔開,表示一輛貨車需要從 xx 城市運輸貨物到 yy 城市,保證 x \neq yx​=y

共有 qq 行,每行乙個整數,表示對於每一輛貨車,它的最大載重是多少。

如果貨車不能到達目的地,輸出 -1−1。

輸入 #1複製

4 3

1 2 4

2 3 3

3 1 1

31 3

1 41 3

輸出 #1複製

思路

這題floyd肯定是不能做的,考慮其他辦法。

類似於靜態樹上求節點之間的最小邊權可做。

顯然這顆靜態樹的邊權要盡可能的大,且注意到很多較小的重邊是不用去跑的,所以考慮只把最大的邊加入連通塊,捨棄小的重邊。

對於兩座城市,如果不在同乙個連通塊內,當然是不能跑的,輸出-1;

如果在同乙個連通塊內,因為邊點和詢問的數量級過大,顯然正常的列舉是不足以勝任此題要求的。

這就涉及到靜態樹上求節點之間的最小邊權問題。

對於這種問題,可以上樹鏈剖分用線段樹來維護,也可以用樹上問題的經典解法lca來求解。

在處理 f 陣列的過程中維護乙個 dis 陣列用以表示點間最小邊權值即可。

code

1 #include 2

#define dbg(x) cout << #x << "=" << x << endl

3#define eps 1e-8

4#define pi acos(-1.0)56

using

namespace

std;

7 typedef long

long

ll;8

9 templateinline void read(t &res)

1015

16namespace

_buff

24return ib == ie ? -1 : *ib++;25}

26}2728

intqread()

36if (c == '-'

) 40

for (; c >= '

0' && c <= '

9'; c =getc())

43return pos ? ret : -ret;44}

4546

const

int maxn = 1e5 + 7;47

48int

n, m, cnt;

49int head[maxn << 1], edge[maxn << 1], nxt[maxn << 1

];50

int fa[maxn], f[maxn][30], depth[maxn], w[maxn << 1

];51

int dis[maxn][30

];52

53bool

vis[maxn];

5455

struct

node e[maxn << 1

];58

59bool

cmp(node a, node b)

6263

void buildgraph(int u, int v, int

c) 70

71int fid(int

x) 74

75void

join()

80for ( int i = 1; i <= m; ++i ) 88}

89}9091

void dfs(int x)

101}

102}

103104

int lca(int x, int y)

109if(depth[x]

110 swap(x, y);//

保證x是比y深的

111for ( int i = 20; i >= 0; --i )

116}

117if(x == y)

120for ( int i = 20; i >= 0; --i )

125}

126 ans = min(ans, min(dis[x][0], dis[y][0

]));

127return ans;///

跳完最後一步

128}

129130

intmain()

131136

join();

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

144}

145for ( int i = 1; i <= 20; ++i )

152}

153int

q;154 cin >>q;

155for ( int i = 1; i <= q; ++i )

160return0;

161 }

view code

P1967 貨車運輸 生成樹 LCA

a國有n座城市,編號從 1到n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。看我蒻到把雙向邊連成單向邊debug了一上午。很顯然,如果只有乙個詢問,我們貪心地連邊直到起點和終點連通即...

P1967 貨車運輸

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

P1967 貨車運輸

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