Problem Link

题目描述

A国有n座城市,编号从1到n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

输入格式

第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。

接下来 mm行每行 3 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,0000<n<1,000,0<m<10,000,0<q<1,000;

对于 %60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q< 1,0000<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,0000<n<10,000,0<m<50,000,0<q<30,000,0≤z≤100,000。


最大生成树 + LCA


#include<bits/stdc++.h>
using namespace std;
const int maxm = 50000 + 5;
const int maxn = 10000 + 5;
const int inf = 1e9 - 1; // 坑点, 坑了我2h
int n, m, q;
int fa[maxn];
int find(int x){
if(x == fa[x])
return x;
else
return fa[x] = find(fa[x]);
}
//如果两个点不在一个联通块(点集<并查集>)中,则输出-1
struct G{
int x, y, z;
bool operator < (const G & nxt){
return z > nxt.z;
}
}g[maxm];
//保存初始图
struct E{
int to, z;
};
vector <E> e[maxn];
//保存最大生成树的图<贪心思想>
void kruscal(){
sort(g + 1, g + 1 + m);
for(int i = 1;i <= n;i ++){
fa[i] = i;
}
for(int i = 1;i <= m;i ++){
int x = find(g[i].x);
int y = find(g[i].y);
int z = g[i].z;
if(x == y)
continue;
fa[x] = y;
e[g[i].x].push_back(E{g[i].y, z});
e[g[i].y].push_back(E{g[i].x, z});
}
}
//kruscal最大生成树&建图
bool vis[maxn];
int f[maxn][21];//f[i,j] : i的2^j辈祖先
int w[maxn][21];//w[i,j] : i到f[i,j]的路径上最短的一条边(限制了货车的限重)
int dep[maxn];
void dfs(int x){
vis[x] = 1;
for(int i = 0;i < e[x].size();i ++){
int y = e[x][i].to, z = e[x][i].z;
if(vis[y])continue;
dep[y] = dep[x] + 1;
f[y][0] = x;
w[y][0] = z;//子(y)父(x)之间距离为当前边权
dfs(y);
}
}
//lca预处理
int lca(int x, int y){
if(find(x) != find(y)){
return -1;
}
if(dep[x] < dep[y])
swap(x, y);
int ans = inf;//先置infinite
for(int i = 20;i >= 0;i --){
if(dep[f[x][i]] >= dep[y]){
ans = min(ans, w[x][i]);
//这里是x到与y同一高度的祖先的路径上的最小值
x = f[x][i];
}
}
if(x == y)
return ans;
for(int i = 20;i >= 0;i --){
if(f[x][i] != f[y][i]){
ans = min(ans, min(w[x][i], w[y][i]));
//这里是两条路径(x -> f[x][i], y -> f[y][i])上的最小边权
x = f[x][i];
y = f[y][i];
}
}
ans = min(ans, min(w[x][0], w[y][0]));
//还有到真正的lca的两条边的最小值
return ans;
}//注意: 这里的lca返回的是 path: x -> lca(x, y) & lca(x, y) -> y 的路径上的最小边权, 即货车限重
int main(){
scanf("%d%d", &n, &m);
for(int i = 1;i <= m;i ++){
scanf("%d%d%d", &g[i].x, &g[i].y, &g[i].z);
}
kruscal();
for(int i = 1;i <= n;i ++){
if(!vis[i]){
dep[i] = 1;
dfs(i);
f[i][0] = i;
w[i][0] = inf;
}
}
//预处理
for(int i = 1;i < 20;i ++){
for(int j = 1;j <= n;j ++){
f[j][i] = f[f[j][i - 1]][i - 1];
w[j][i] = min(w[j][i - 1], w[f[j][i - 1]][i - 1]);
}
}
//预处理
scanf("%d", &q);
for(int i = 1;i <= q;i ++){
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", lca(x, y));
}
return 0;
}

[NOIP2013][LGOJ P1967]货车运输的更多相关文章

  1. 洛谷 P1967 货车运输

    洛谷 P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在 ...

  2. P1967 货车运输

    P1967 货车运输最大生成树+lca+并查集 #include<iostream> #include<cstdio> #include<queue> #inclu ...

  3. 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增

    倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...

  4. Luogu P1967 货车运输(Kruskal重构树)

    P1967 货车运输 题面 题目描述 \(A\) 国有 \(n\) 座城市,编号从 \(1\) 到 \(n\) ,城市之间有 \(m\) 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 \ ...

  5. 【杂题总汇】NOIP2013(洛谷P1967) 货车运输

    [洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...

  6. [NOIP2013] 提高组 洛谷P1967 货车运输

    题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...

  7. 洛谷—— P1967 货车运输 || COGS——C 1439. [NOIP2013]货车运输

    https://www.luogu.org/problem/show?pid=1967#sub  ||  http://www.cogs.pro/cogs/problem/problem.php?pi ...

  8. 洛谷P1967 货车运输 [noip2013] 图论

    正解:kruskal+LCA 解题报告: 哇真实心痛了...明明都没多少时间了我居然耗了一个上午+一个中午在上面?哭死辽我QAQ果然菜是原罪QAQ 然后这题,我先港下60pts做法趴?话说其实我觉得我 ...

  9. P1967 货车运输(倍增LCA,生成树)

    题目链接: https://www.luogu.org/problemnew/show/P1967 题目描述 A国有n座城市,编号从 1到n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制, ...

随机推荐

  1. js内建函数reduce()

    reduce函数,是ECMAScript5规范中出现的数组方法.在平时的工作中,相信大家使用的场景并不多,一般而言,可以通过reduce方法实现的逻辑都可以通过forEach方法来变相的实现,虽然不清 ...

  2. Linux常用操作命令大全

    0.新建操作:1.查看操作    2.删除操作 3.复制操作    4.移动操作:5.重命名操作: 6.解压压缩操作    7.上传文件工具    8.ln.file和touch命令 9.查找操作命令 ...

  3. 【Golang】vscode 设置 go 开发环境

    步骤 1. 始 Golang 语言开发选择一款合适的编辑器,能加速你敲字的灵感,这里推荐微软的 Visual Studio Code,简称 vscode. 2. 安装 go 插件 首先需要安装 go ...

  4. python数学math和random模块

    math模块 关注公众号"轻松学编程"了解更多. 在使用math模块时要先导入 # 导入模块 import math 1.math.ceil(num) 对num进行向上取整 num ...

  5. Python3网络学习案例二:traceroute详解

    1. 写在前面 本文是基于上一篇"ping详解"写的: 不同操作系统下的命令也不同,本文仅针对windows系统,命令为"tracert xxx",效果如下 2 ...

  6. Nginx是什么?有什么用?

    一.Nginx是什么 Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服 ...

  7. 『JVM』我不想知道我是怎么来滴,我就想知道我是怎么没滴

    我是风筝,公众号「古时的风筝」,一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在 ...

  8. 快快使用ModelArts,零基础小白也能玩转AI!

    摘要: 走过路过不要错过,看Copy攻城狮如何借力华为云ModelArts玩转AI. "自2018年10月发布以来,ModelArts累计服务了众多行业十几万开发者,通过基础平台的完备性和面 ...

  9. SQL2005数据库可疑的解决方法

    sqlserver数据库标注为可疑的解决办法 一般引起可疑的原因是突然断电,服务器死机,强制关机导致正在运行的数据库文件损坏,需要进行修复.方法一:USE MASTER GOSP_CONFIGURE ...

  10. shell 之 -f -z -e -o -a -d

    # -f 文件存在 if[ -f /etc/sysconfig/network ]; then ./etc/sysconfig/network fi # -z 字串为空/ -o or / -a and ...