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. Jupyter Notebook使用教程

    关于安装我就不说了,可以参考知乎https://zhuanlan.zhihu.com/p/33105153(总结的很全面) 首先打开Jupyter Notebook后,新建notebook:点击右上角 ...

  2. JavaScript实现基于对象的栈

    class Stack { constructor() { this.count = 0; this.items = {}; } push(element) { this.items[this.cou ...

  3. Disruptor 使用简介

    [开发总结]Disruptor 使用简介 在极客时间看到王宝令老师关于 Disruptor 的一篇文章,觉得很有意思.看完之后又在网上找到一些其他关于Disruptor 的资料看了一下. 现在写篇文章 ...

  4. 4G DTU模块带有MQTT协议吗?

    DTU作为一种通讯设备,其应用场合十分广泛.从广义上讲,在进行通信时,传输数据链路两端负责发送数据信息的模块单元都称之为DTU,在它的作用下对所传信息格式转换和数据整理校验.在狭义上的定义,DTU一般 ...

  5. NB-IOT的应用场景有哪些

    虽然抄表.停车.井盖监测等应用是最为常见的示范,但若低功耗广域网络仅限于这几个领域,则整个产业的规模就显得太小了.实际上,经过近两年的探索,目前示范应用的数量已有数十个,分布在各行各业,带来了大量的机 ...

  6. 20200726_java爬虫_使用HttpClient模拟浏览器发送请求

    浏览器获取数据: 打开浏览器 ==> 输入网址 ==> 回车查询 ==> 返回结果 ==> 浏览器显示结果数据 HttpClient获取数据: 创建HttpClient ==& ...

  7. Java基础知识(三)

    一.hashCode 与 equals (重要) 面试官可能会问你:"你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?" 1 ...

  8. Docker(10)- docker create 命令详解

    如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html 作用 创建一个新的容器但不启动它 ...

  9. 一文搞懂后台高性能服务器设计的常见套路, BAT 高频面试系列

    微信搜索「编程指北」,关注这个写干货的程序员,回复「资源」,即可获取后台开发学习路线和书籍 先赞后看,养成习惯~ 前言 金九银十,又是一年校招季. 经历过,才深知不易.最近,和作为校招面试官的同事聊了 ...

  10. SU+GIS,让SketchUp模型在地图上活起来

    一.SU+GIS的场景展示 skp与卫星地图和倾斜摄影模型相结合人工模型与实景模型完美融合 这么一看是不是直接秒杀了单纯看看skp后联想的规划效果? 二.如何快速把草图大师的结果和GIS结合呢?在图新 ...