题意:给出一颗n个点的图,q个询问,每次询问u到v的路径中最小的边最大是多少。

图的最大生成树有一个性质,对于该图的任意两个点,在树中他们之间路径的最小边最大。

由于这个图不一定联通,于是我们对它的联通块都求一次最大生成树。

每次询问就变成了在最大生成树上找出u到v路径的最小边。

这个显然可以用LCA维护点到它的2^x祖先之间的边的最小值来解决。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... const int DEG=;
struct Edge{int p, next, w;}edge[N<<];
struct Node{int u, v, w;}node[N*];
int head[N], cnt=, F[N], from[N];
int fa[N][DEG], mi[N][DEG], deg[N];
queue<int>que; void add_edge(int u, int v, int w){edge[cnt].p=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++;}
bool comp(Node a, Node b){return a.w>b.w;}
int find(int x){return F[x]==-?x:F[x]=find(F[x]);}
void Kruscal(int n){
mem(F,-); sort(node+,node+*n+,comp);
FOR(i,,*n) {
int u=node[i].u, v=node[i].v, t1=find(u), t2=find(v);
if (t1!=t2) add_edge(u,v,node[i].w), add_edge(v,u,node[i].w), F[t1]=t2;
}
}
void BFS(int root){
deg[root]=; fa[root][]=root; mi[root][]=INF; que.push(root);
while (!que.empty()) {
int tmp=que.front(); que.pop();
FO(i,,DEG) fa[tmp][i]=fa[fa[tmp][i-]][i-], mi[tmp][i]=min(mi[tmp][i-],mi[fa[tmp][i-]][i-]);
for (int i=head[tmp]; i; i=edge[i].next) {
int v=edge[i].p;
if (v==fa[tmp][]) continue;
deg[v]=deg[tmp]+; fa[v][]=tmp; mi[v][]=edge[i].w; que.push(v);
}
}
}
int LCA(int u, int v){
int ans=INF;
if (deg[u]>deg[v]) swap(u,v);
int hu=deg[u], hv=deg[v], tu=u, tv=v;
for (int det=hv-hu, i=; det; det>>=, ++i) if (det&) ans=min(ans,mi[tv][i]), tv=fa[tv][i];
if (tu==tv) return ans;
for (int i=DEG-; i>=; --i) {
if (fa[tu][i]==fa[tv][i]) continue;
ans=min(ans,mi[tu][i]); ans=min(ans,mi[tv][i]);
tu=fa[tu][i]; tv=fa[tv][i];
}
return min(ans,min(mi[tu][],mi[tv][]));
}
int main ()
{
int n, m, q, u, v;
scanf("%d%d",&n,&m);
FOR(i,,m) scanf("%d%d%d",&node[i].u,&node[i].v,&node[i].w);
Kruscal(m);
int pos=;
FOR(i,,n) {
int v=find(i);
if (from[v]==) from[v]=, BFS(v);
}
scanf("%d",&q);
while (q--) {
scanf("%d%d",&u,&v);
if (find(u)!=find(v)) {puts("-1"); continue;}
printf("%d\n",LCA(u,v));
}
return ;
}

luogu 1967 货车运输(最大生成树+LCA)的更多相关文章

  1. [luogu 1967]货车运输

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

  2. kruskal - 倍增 - 并查集 - Luogu 1967 货车运输

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

  3. 【NOIP2013】货车运输 最大生成树+LCA

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

  4. LUOGU P1967 货车运输(最大生成树+树剖+线段树)

    传送门 解题思路 货车所走的路径一定是最大生成树上的路径,所以先跑一个最大生成树,之后就是求一条路径上的最小值,用树剖+线段树,注意图可能不连通.将边权下放到点权上,但x,y路径上的lca的答案不能算 ...

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

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

  6. codevs3287货车运输(最小生成树+LCA)

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

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

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

  8. TZOJ 4848 货车运输(最大生成树+倍增lca)

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

  9. $Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$

    $Luogu$ $Sol$ 首先当然是构建一棵最大生成树,然后对于一辆货车的起点和终点倍增跑$lca$更新答案就好.记得预处理倍增的时候不仅要处理走了$2^i$步后是那个点,还有这中间经过的路径权值的 ...

随机推荐

  1. 微信小程序居中代码

    html页面: { text-align:center; } wxss页面: { width: 100%; height: 100%; display: flex; justify-content: ...

  2. DSP5509的USB协议开发

    1. 使用的板子 2. 原理图相关,这个1.5K的上拉电阻,全速和高速上拉在D+,低速上拉在D- 3. 中断处理函数没有搞明白是什么意思?这个工程我怎么基本看不懂? interrupt void US ...

  3. 【JUC源码解析】ThreadPoolExecutor

    简介 ThreadPoolExecutor,线程池的基石. 概述 线程池,除了用HashSet承载一组线程做任务以外,还用BlockingQueue承载一组任务.corePoolSize和maximu ...

  4. 八、Django之Models(译)

    模型(Models) 模型是你的数据的唯一的.确定的信息源. 它包含你所储存数据的必要字段和行为. 通常,每个模型对应数据库中唯一的一张表. 基础: 每个模型都是一个Python类,它们都是djang ...

  5. Django的简介

    一.MTV模型 Django的MTV模式: Model(模型):和数据库相关的.负责业务对象与数据库的对象(ORM) Template(,模板):放所有的HTML文件 模板语法:目的是将变量(数据库内 ...

  6. 为CentOS系统配置防火墙设置

    在各种操作系统中,为了保护系统在网络中是相对安全的,我们通常都会给操作系统配置防火墙,通过配置防火墙来限定哪些流量可以进来,哪些流量可以出去,通过这样的一种方式,可以有效的管理系统的流量,从一定程度上 ...

  7. 深入了解MySQL存储索引

    (一)关于存储引擎 创建合适的索引是SQL性能调优中最重要的技术之一.在学习创建索引之前,要先了解MySql的架构细节,包括在硬盘上面如何组织的,索引和内存用法和操作方式,以及存储引擎的差异如何影响到 ...

  8. 智慧树mooc自动刷课代码

    最近学习javaScript和JQuery,恰好还有一门mooc没有看.结合学习的知识和其他人的代码:撸了一个自动播放课程的代码,同时自动跳过单章的测试题. 用电脑挂着不动就完事了. 如下: var ...

  9. linux源码学习-for_each_cpu

    刚开始读linux源码,第一眼就看到了这个很有意思的函数族,周末好好研究一下 3.13 这个组都是宏定义for循环,分析的时候注意到cpumask_next(),它在一个文件中定义了两次,还不是重载, ...

  10. 【RL系列】SARSA算法的基本结构

    SARSA算法严格上来说,是TD(0)关于状态动作函数估计的on-policy形式,所以其基本架构与TD的$v_{\pi}$估计算法(on-policy)并无太大区别,所以这里就不再单独阐述之.本文主 ...