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]货车运输的更多相关文章

  1. NOIP 2013 货车运输【Kruskal + 树链剖分 + 线段树 】【倍增】

    NOIP 2013 货车运输[树链剖分] 树链剖分 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在 ...

  2. NOIP 2013 货车运输 最大生成树加DFS巧妙AC

    #include<set> #include<map> #include<cmath> #include<queue> #include<stac ...

  3. NOIP 2013货车运输

    当然这题有很多做法,但是我看到没有人写DSU的很惊奇 按照之前做连双向边题的经验,这题可以用并查集维护联通 然后对于每个询问\(x,y\),考虑启发式合并 当两个点集\(x,y\)合并时,一些涉及到其 ...

  4. NOIP提高组 2013货车运输

    觉得题目水的离开 不屑的大佬请离开 不会图论的请离开 ……. 感谢您贡献的访问量 ————————————华丽的分割线———————————— 题面: 题目描述 A 国有 n 座城市,编号从 1 到 ...

  5. 【NOIP】提高组2013 货车运输

    [算法]最大生成树+LCA(倍增) [题解]两点间选择一条路径最小值最大的路径,这条路径一定在最大生成树上,因为最大生成树就是从边权最大的边开始加的. 先求原图的最大生成树(森林),重新构图,然后用一 ...

  6. 题解 【luoguP1967 NOIp提高组2013 货车运输】

    题目链接 题解 题意 给你一个无向图,求两个点之间的一条路径,使路径上的最小值最大 算法:Kruskal最大生成树+倍增lca 分析 首先容易知道,答案一定在该图的最大生成树上 之后问题便转换成了树上 ...

  7. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...

  8. [Noip 2013 Day1-3] 货车运输 做法总结

    [Noip 2013 Day1-3] 货车运输 做法总结 Online Judge:Luogu-1967 Label:启发式合并,离线,整体二分,按秩合并,倍增,最大生成树 打模拟离线赛时做到,顺便总 ...

  9. NOIP2013 货车运输 (最大生成树+树上倍增LCA)

    死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...

随机推荐

  1. I Know Alpha冲刺随笔集

    Alpha冲刺 Day1 Alpha冲刺 Day2 Alpha冲刺 Day3 Alpha冲刺 Day4 Alpha冲刺 Day5 Alpha冲刺 Day6 Alpha冲刺 Day7 Alpha冲刺 D ...

  2. 201621123062《java程序设计》第九周作业总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 思维导图1:(对集合部分做了一些改动和细化) 思维导图2:(泛型) 1.2 选做:收集你认为有用的代码片段 代 ...

  3. 20162302 实验三《敏捷开发与XP实践》实验报告

    实 验 报 告 课程:程序设计与数据结构 姓名:杨京典 班级:1623 学号:20162302 实验名称:敏捷开发与XP实践 实验器材:装有IdeaU的联想拯救者80RQ 实验目的与要求:1.代码的格 ...

  4. 项目Beta预备

    项目名称:城市安全风险管控系统 Beta预备: 讨论组长是否重选的议题和结论 项目组长可以说是一个团队的灵魂和核心.一个好的领导者可以激发团队成员的工作热情,提高开发效率,保质保量的完成工作.虽然在A ...

  5. Flask 扩展 Flask-RESTful

    Flask路由可以指定HTTP请求方法,并在请求函数中根据不同的请求方法,执行不同的逻辑.这样实现一个Restful的请求已经相当简单了 Flask还有更简便的方法,就是其Flask-RESTful扩 ...

  6. PHP获取短信验证码

    PHP如何获取短信验证码?以下是创蓝253短信平台下的PHP接口代码案例:   <?php header("Content-type:text/html; charset=UTF-8& ...

  7. Xamarin控件使用之ListView

    listview单列多行的显示,以后再加多列多行的实例. [Activity(Label = "GraphicAll", LaunchMode = LaunchMode.Singl ...

  8. Linux的安装和使用技巧

    LinuxCentOs开始设置一个普通的用户,如果想进入root用户,可以su然后设置密码,然后第二次再次输入su,然后输入相同的密码就可以进去了 有很多命令需要在root下才能执行,但是在创建时却是 ...

  9. java希尔排序

    java希尔排序 1.基本思想: 希尔排序也成为"缩小增量排序",其基本原理是,现将待排序的数组元素分成多个子序列,使得每个子序列的元素个数相对较少,然后对各个子序列分别进行直接插 ...

  10. 深度学习之 GAN 进行 mnist 图片的生成

    深度学习之 GAN 进行 mnist 图片的生成 mport numpy as np import os import codecs import torch from PIL import Imag ...