[NOIp 2013]货车运输
Description
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
Input
输入文件名为 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 。
Output
输出文件名为 truck.out。
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货
车不能到达目的地,输出-1。
Sample Input
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
Sample Output
3
-1
3
Hint
对于 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。
题解
$Kruskal$+$LCA$+并查集
建最大生成森林(以保证联通性的情况下最大化瓶颈路径)。
并查集判断是否联通。
若联通,$LCA$出路径上的最短边。
#include<map>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
#define RE register
#define IL inline
using namespace std;
const int N=;
const int M=; IL int Min(const int &a,const int &b) {return a<b ? a:b;} int n,m,q,lim,x,y;
struct tt
{
int from,to,cost;
}lin[M+];
IL bool comp(const tt &a,const tt &b) {return a.cost>b.cost;} int set[N+];
IL int Find(int r) {return set[r] ? set[r]=Find(set[r]):r;}
IL void Kruskal(); struct ss
{
int to,next,cost;
}edge[N*+];
int path[N+],top;
IL void Add(int u,int v,int c); bool vis[N+];
int fa[N+][],minn[N+][],dep[N+];
void Dfs(int r,int depth);
IL void RMQ(); IL int LCA(int x,int y); int main()
{
scanf("%d%d",&n,&m);lim=log2(n);
for (RE int i=;i<=m;i++) scanf("%d%d%d",&lin[i].from,&lin[i].to,&lin[i].cost);
Kruskal();
for (RE int i=;i<=n;i++) if (!vis[i]) Dfs(i,);
RMQ();
scanf("%d",&q);
while (q--)
{
scanf("%d%d",&x,&y);
int a=Find(x);
int b=Find(y);
if (a!=b) printf("-1\n");
else printf("%d\n",LCA(x,y));
}
return ;
} IL void Kruskal()
{
sort(lin+,lin+m+,comp);
int cnt=;
for (RE int i=;i<=m;i++)
{
int q=Find(lin[i].from);
int p=Find(lin[i].to);
if (p!=q)
{
set[p]=q;
cnt++;
Add(lin[i].from,lin[i].to,lin[i].cost);
Add(lin[i].to,lin[i].from,lin[i].cost);
if (cnt==n-) break;
}
}
}
IL void Add(int u,int v,int c)
{
edge[++top].to=v;
edge[top].next=path[u];
edge[top].cost=c;
path[u]=top;
}
void Dfs(int r,int depth)
{
vis[r]=;
dep[r]=depth;
for (RE int i=path[r];i;i=edge[i].next) if (!vis[edge[i].to])
{
fa[edge[i].to][]=r;
minn[edge[i].to][]=edge[i].cost;
Dfs(edge[i].to,depth+);
}
}
IL void RMQ()
{
for (RE int t=;t<=lim;t++)
for (RE int i=;i<=n;i++)
{
fa[i][t]=fa[fa[i][t-]][t-];
minn[i][t]=Min(minn[i][t-],minn[fa[i][t-]][t-]);
}
}
IL int LCA(int x,int y)
{
int ans=2e9;
if (dep[x]<dep[y]) swap(x,y);
for (RE int i=lim;i>=;i--) if (dep[x]-(<<i)>=dep[y])
{
ans=Min(ans,minn[x][i]);
x=fa[x][i];
}
if (x!=y)
{
for (RE int i=lim;i>=;i--) if (fa[x][i]!=fa[y][i])
{
ans=Min(ans,minn[x][i]);
ans=Min(ans,minn[y][i]);
x=fa[x][i];
y=fa[y][i];
}
ans=Min(ans,minn[x][]);
ans=Min(ans,minn[y][]);
x=fa[x][];
y=fa[y][];
}
return ans;
}
[NOIp 2013]货车运输的更多相关文章
- NOIP 2013 货车运输【Kruskal + 树链剖分 + 线段树 】【倍增】
NOIP 2013 货车运输[树链剖分] 树链剖分 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在 ...
- NOIP 2013 货车运输 最大生成树加DFS巧妙AC
#include<set> #include<map> #include<cmath> #include<queue> #include<stac ...
- NOIP 2013货车运输
当然这题有很多做法,但是我看到没有人写DSU的很惊奇 按照之前做连双向边题的经验,这题可以用并查集维护联通 然后对于每个询问\(x,y\),考虑启发式合并 当两个点集\(x,y\)合并时,一些涉及到其 ...
- NOIP提高组 2013货车运输
觉得题目水的离开 不屑的大佬请离开 不会图论的请离开 ……. 感谢您贡献的访问量 ————————————华丽的分割线———————————— 题面: 题目描述 A 国有 n 座城市,编号从 1 到 ...
- 【NOIP】提高组2013 货车运输
[算法]最大生成树+LCA(倍增) [题解]两点间选择一条路径最小值最大的路径,这条路径一定在最大生成树上,因为最大生成树就是从边权最大的边开始加的. 先求原图的最大生成树(森林),重新构图,然后用一 ...
- 题解 【luoguP1967 NOIp提高组2013 货车运输】
题目链接 题解 题意 给你一个无向图,求两个点之间的一条路径,使路径上的最小值最大 算法:Kruskal最大生成树+倍增lca 分析 首先容易知道,答案一定在该图的最大生成树上 之后问题便转换成了树上 ...
- Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...
- [Noip 2013 Day1-3] 货车运输 做法总结
[Noip 2013 Day1-3] 货车运输 做法总结 Online Judge:Luogu-1967 Label:启发式合并,离线,整体二分,按秩合并,倍增,最大生成树 打模拟离线赛时做到,顺便总 ...
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...
随机推荐
- Elasticsearch安装详解
本文只介绍在windows上的安装和配置,其他安装和配置请参见官方文档 ES在windows上安装需下载zip安装包,解压后bin目录下有个 elasticsearch-service.bat 文件. ...
- 指令-arContentedit-可编辑的高度自适应的div
<div ar-contentedit="true" contenteditable="true" contenteditable="pla ...
- C语言——第七周作业
题目 题目一:求交错序列前N项和 1.实验代码 #include <stdio.h> int main() { int n , i , b ; , a , c ; scanf(" ...
- 【iOS】swift 保持代码优美的10个方法
这篇Swift风格指南与你看到的其他的指南有所不同,此篇指南主要焦点集中在打印和Web展示的可读写上.我们创建此篇风格指南的目的,是为了让我们的图书.教程以及初学者套件中的代码保持优美和一致,即使我们 ...
- Digilent Xilinx USB Jtag cable
Digilent Xilinx USB Jtag cable 安装环境 操作系统:fedora 20 64bit 源链接:https://wiki.gentoo.org/wiki/Xilinx_USB ...
- nyoj 韩信点兵
描述相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排.五人一排.七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了.输入3个非负整数a,b,c ,表示每种队形排尾的人数 ...
- Python内置函数(56)——locals
英文文档: locals() Update and return a dictionary representing the current local symbol table. Free var ...
- Python内置函数(11)——complex
英文文档: class complex([real[, imag]]) Return a complex number with the value real + imag*1j or convert ...
- jmeter入门(02)测试报告各项指标含义
一.名词定义(时间单位ms) 1.聚合报告 Sample:本次测试场景共运行多少个请求: Average:平均响应时间: Median:统计意义上的响应时间中值: 90% line:所有线程中90%的 ...
- Ionic 2 开发(一)_安装与目录结构
由于公司开始使用后ionic 进行前段开发,现在需要学习下ionic,虽然是后台开发,但是还是有必要了解下的 安装Node.js 官网:http://nodejs.cn/ 自行下载安装 安装Ionic ...