• luogu P1967 货车运输


    题目描述

    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

    说明

    对于 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。

    /*
        这道题的基本思路在于求最大生成树,构建最大生成树的图
        然后问题相当于转化成求两点之间一条链上的最小值,因为
        这是已经构建出了最大生成树。
        利用倍增的思想,g[i][j]表示i,这个点向上跳j步,这之间
        的最小值,与求lca的f[i][j]很像(基本一样的) 
      自己yy不难理解
    */ #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <string> using namespace std; const int N = 1e4 + 10; #define oo 99999999 struct Node{ int u, v, w; }S[N * 5]; struct Edge{ int u, v, w, nxt; }E[N << 1]; int now = 1, n, m, js; int head[N], p[N], f[N][25], g[N][25], deep[N]; inline int read(){ int x = 0; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x; } inline bool cmp(Node a, Node b){ return a.w > b.w; } int getf(int x){ return p[x] == x ? x : p[x] = getf(p[x]); } void add(int u, int v, int w){ E[now].v = v; E[now].w = w; E[now].nxt = head[u]; head[u] = now ++; } inline void Kruskal(){ for(int i = 1, doen = 1; i <= (m << 1) && doen < n; i ++) { int u = S[i].u, v = S[i].v; int pu = getf(u), pv = getf(v); if(pu != pv) { p[pu] = pv; add(u, v, S[i].w); add(v, u, S[i].w); doen ++; } } } void make_deep(int u, int depth){ deep[u] = depth; for(int i = head[u]; ~ i; i = E[i].nxt) { int v = E[i].v; if(!deep[v]) { f[v][0] = u; g[v][0] = E[i].w; make_deep(v, depth + 1); } } } inline void make_jump(){ for(int j = 1; (1 << j) <= n; j ++) for(int i = 1; i <= n; i ++) if(f[i][j - 1]) f[i][j] = f[f[i][j - 1]][j - 1], g[i][j] = min(g[i][j - 1], g[f[i][j - 1]][j - 1]); } inline int lca(int x, int y){ int ret = oo; if(x == y) return 0; if(deep[x] < deep[y]) swap(x, y); int k = log2(deep[x]); for(int i = k; i >= 0; i --) { if(deep[f[x][i]] >= deep[y]) { ret = min(ret, g[x][i]); x = f[x][i]; } } if(x == y) return ret; for(int i = k; i >= 0; i --) { if(f[x][i] != f[y][i]) { ret = min(ret, min(g[x][i], g[y][i])); x = f[x][i]; y = f[y][i]; } } ret = min(ret, min(g[x][0], g[y][0])); return ret; } int main() { n = read(); m = read(); for(int i = 1; i <= n; i ++) head[i] = -1, p[i] = i; for(int i = 1; i <= m; i ++) S[i].u = read(), S[i].v = read(), S[i].w = read(); sort(S + 1, S + m + 1, cmp); Kruskal(); for(int i = 1; i <= n; i ++) if(!deep[i]) make_deep(i, 1); make_jump(); int T = read(); while(T --) { int x = read(), y = read(); if(getf(x) != getf(y)){ printf("-1 "); continue ; } int answer = lca(x, y); printf("%d ", answer); } return 0; }
  • 相关阅读:
    python的xpinyin模块:汉字转拼音
    中文报错SyntaxError: Non-UTF-8 code starting with 'xe6' in file
    "底层逻辑”是什么意思?
    【Golang】关于Go中logrus的用法
    【Golang】 关于Go语言中的锁
    【Golang】Go 通过结构(struct) 实现接口(interface)
    【Golang】Go语言之log的使用
    【Golang】Go中时间(time)的用法以及gorm处理时间戳
    【Golang】Go中三个点(...)用法
    一文彻底掌握Apache Hudi异步Clustering部署
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7787539.html
Copyright © 2020-2023  润新知