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. 线上问题排查,一不小心踩到阿里的 arthas坑了

    最近帮新来的校招同学排查一个线上问题,问题本身不是很难,但是过程中踩到了一个arthas的坑,挺有意思的. 同时,也分享下在排查过程中使用的一些比较实用的工具,包括tcpdump.arthas.sim ...

  2. 09 Servlet中间服务 连接前段和后端

    import  导入    在当前类中使用外包中的类时使用 cookies 缓存 Alt + enter 提示快捷键 Servlet 服务  (连接前段和后端) Servlet本质就是Java类 Ja ...

  3. LORA串口无线数据透明传输终端ZSL311

    ZSL311是由成都众山科技生产销售的一款LORA串口无线数据透明传输终端,采用的是LoRa扩频技术来进行无线数据传输,同时提供RS485和RS232串口,为用户提供全透明数据传输模式.支持星形.Me ...

  4. Hadoop基础------>MR框架-->WordCount

    认识Mapreduce Mapreduce编程思想 Mapreduce执行流程 java版本WordCount实例 1. 简介: Mapreduce源于Google一遍论文,是谷歌Mapreduce的 ...

  5. VC获取文件后缀名

    VC获取文件后缀名 2011-07-28 10:30:50|  分类: Visual C++ and O |  标签: |举报 |字号大中小 订阅     1. CString GetSuffix(C ...

  6. Flink的DataSource三部曲之一:直接API

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. Simulink代码自动生成(一)

    前面介绍了MDB的设计思想并对比了它和传统的嵌入式软件开发之间的差异,现在开始使用Simulink工具演示模型的搭建和C代码的自动生成过程. Matlab版本:R2018B 一.算法模型的搭建 搭建一 ...

  8. VUE自定义(有限)库存日历插件

    开发过程中遇到一个令人发指的,一个element-ui无法满足的日历需求, 改造其日历插件的代价太大,于是索性自己手写一个,需求如下: 1. 根据开始.结束时间计算时间覆盖的月份,渲染有限的可选择日期 ...

  9. c#分割习题

    2.从一个记录了学生成绩的文本文档,每个学生成绩是一行,每行是用 | 分割的数据,用 | 分割的域分别是姓名.年龄.成绩.年级,写程序取出各个年级成绩最高学生的成绩.年级放到集合中.提示:(1)使用 ...

  10. 内网渗透 day11-免杀框架

    免杀框架 目录 1. venom框架 2. shelltel框架 3. backdoor factory(BDP) 1. venom框架 cd venom进入venom文件夹中./venom.sh进入 ...