洛谷 P1967 貨車運輸
阿新 • • 發佈:2018-07-20
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[10005View Code][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; }
洛谷 P1967 貨車運輸