1. 程式人生 > >洛谷 P1967 貨車運輸

洛谷 P1967 貨車運輸

ans 現在 span ret 思路 swap sin 生成 tps

      洛谷 P1967 貨車運輸

題目描述

A 國有 n 座城市,編號從 1 到 n ,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物, 司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。

輸入輸出格式

輸入格式:

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

接下來 m 行每行 3 個整數 x, y, z,每兩個整數之間用一個空格隔開,表示從 x 號城市到 y 號城市有一條限重為 z的道路。註意: x 不等於 y ,兩座城市之間可能有多條道路 。

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

接下來 q 行,每行兩個整數 x、y,之間用一個空格隔開,表示一輛貨車需要從 x 城市運輸貨物到 y 城市,註意: x 不等於 y 。

輸出格式:

共有 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

說明

對於 30% 的數據, 0 < n < 1,000,0 < m < 10,000,0 < q< 1,000

對於 60% 的數據, 0 < n < 1,000,0 < m < 50,000,0 < q< 1,000

對於 100% 的數據, 0 < n < 10,000,0 < m < 50,000,0 < q< 30,000,0 ≤ z ≤ 100,000

思路:先求最小生成樹,記錄下最小生成樹中權值最大的邊,然後根據這條邊再求最大生成樹,然後通過求LCA求出最後的答案

技術分享圖片
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m, q, x, y, cnt;
int hd[10005], nxt[20005], to[20005], w[20005];
int p[50005], f[10005
][20], minv[10005][20], dep[10005]; struct edge { int x, y, z; bool operator < (const edge &rhs) const { return z > rhs.z; } } e[50005]; void add(int x, int y, int z) { to[cnt] = y; w[cnt] = z; nxt[cnt] = hd[x]; hd[x] = cnt++; } int fnd(int x) { return p[x] == x ? x : p[x] = fnd(p[x]); } void kruskal() { for(int i = 0; i < m; i++) p[i] = i; sort(e, e+m); for(int i = 0; i < m; i++) if(fnd(e[i].x) != fnd(e[i].y)) { add(e[i].x, e[i].y, e[i].z); add(e[i].y, e[i].x, e[i].z); p[fnd(e[i].x)] = fnd(e[i].y); } } void dfs(int x, int p) { for(int i = hd[x]; ~i; i = nxt[i]) if(i != p) { dep[to[i]] = dep[x] + 1; f[to[i]][0] = x; minv[to[i]][0] = w[i]; dfs(to[i], i ^ 1); } } int lca(int x, int y) { int ans = 100000000; if(dep[x] > dep[y]) swap(x, y); for(int i = 15; i >= 0; i--) if(dep[f[y][i]] >= dep[x]) { ans = min(ans, minv[y][i]); y = f[y][i]; } if(x == y) return ans; for(int i = 15; i >= 0; i--) if(f[x][i] != f[y][i]) { ans = min(ans, min(minv[x][i], minv[y][i])); x = f[x][i]; y = f[y][i]; } return f[x][0] == 0 ? -1 : min(ans, min(minv[x][0], minv[y][0])); } int main() { scanf("%d%d", &n, &m); for(int i = 0; i < m; i++) scanf("%d%d%d", &e[i].x, &e[i].y, &e[i].z); memset(hd, -1, sizeof hd); kruskal(); dep[1] = 1; dfs(1, -1); for(int j = 1; j <= 15; j++) for(int i = 1; i <= n; i++) { f[i][j] = f[f[i][j-1]][j-1]; minv[i][j] = min(minv[i][j-1], minv[f[i][j-1]][j-1]); } scanf("%d", &q); while(q--) scanf("%d%d", &x, &y), printf("%d\n", lca(x, y)); return 0; }
View Code

洛谷 P1967 貨車運輸