描述

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

输入

第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。

接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。

接下来一行有一个整数 q,表示有 q 辆货车需要运货。

接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。

输出

输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。

样例输入

4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3

样例输出

3
-1
3

提示

对于 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。

题意

如上

题解

要使路径上的最小值尽可能大,跑一个最大生成树

然后在查询树上路径最小值的时候,可以跑一个倍增lca

查询u,v的最小值的时候,先找到u,v的公共祖先p,再求min(up的最小值,vp的最小值)

代码

 #include<bits/stdc++.h>
using namespace std; const int maxn=;
const int maxm=;
int deep[maxn],fa[maxn][],dis[maxn][],lg[maxn],vis[maxn],f[maxn],n,m;
vector< pair<int,int> >G[maxn];
struct edge
{
int u,v,w;
bool operator<(const edge &D)const{
return w>D.w;
}
}edges[maxm];
void dfs(int u)
{
vis[u]=;
for(auto X:G[u])
{
int v=X.first;
int w=X.second;
if(vis[v])continue;
fa[v][]=u;
dis[v][]=w;
deep[v]=deep[u]+;
dfs(v);
}
}
void RNQ()
{
for(int j=;(<<j)<=n;j++)
for(int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-],
dis[i][j]=min(dis[i][j-],dis[fa[i][j-]][j-]);
}
int lca(int x,int y)
{
if(deep[x]<deep[y])swap(x,y);
while(deep[x]>deep[y])x=fa[x][lg[deep[x]-deep[y]]-];
if(x==y)return x;
for(int k=lg[deep[x]];k>=;k--)
if(fa[x][k]!=fa[y][k])
x=fa[x][k],y=fa[y][k];
return fa[x][];
}
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
int query(int x,int y)
{
int ans=0x3f3f3f3f,t=deep[x]-deep[y];
for(int i=;i<=;i++)
if(t&(<<i))
ans=min(ans,dis[x][i]),
x=fa[x][i];
return ans;
}
void max_kruskal()
{
int cnt=;
sort(edges,edges+m);
for(int i=;i<m;i++)
{
int u=edges[i].u;
int v=edges[i].v;
int w=edges[i].w;
int fu=find(u);
int fv=find(v);
if(fu!=fv)
{
G[u].push_back({v,w});
G[v].push_back({u,w});
f[fu]=fv;
if(++cnt==n-)break;
}
}
}
int main()
{
memset(dis,0x3f3f3f3f,sizeof dis);
memset(vis,false,sizeof vis);
int u,v,w,q;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)lg[i]=lg[i-]+(<<lg[i-]==i),f[i]=i;
for(int i=;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
edges[i]={u,v,w};
}
max_kruskal();
for(int i=;i<=n;i++)if(!vis[i])dfs(i);
RNQ();
scanf("%d",&q);
for(int i=;i<q;i++)
{
scanf("%d%d",&u,&v);
if(find(u)!=find(v))printf("-1\n");
else
{
int father=lca(u,v);
printf("%d\n",min(query(u,father),query(v,father)));
}
}
return ;
}

TZOJ 4848 货车运输(最大生成树+倍增lca)的更多相关文章

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

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

  2. 【NOIP2013】货车运输 最大生成树+倍增

    题目大意:给你一张n个点m条边的图,有q次询问,每次让你找出一条从x至y的路径,使得路径上经过的边的最小值最大,输出这个最大的最小值. 显然,经过的路径必然在这张图的最大生成树上. 我们求出这个图的最 ...

  3. 「NOIP2013」「LuoguP1967」货车运输(最大生成树 倍增 LCA

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

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

    看到第一篇题解的神奇码风--我决定发一篇码风正常的题解造福人类 这题的做法也非常经典,最大生成树\(+LCA\),相当于先贪心一下,在LCA的时候记录一下当前最小的边权 顺便吐槽一下最后一个测试点: ...

  5. 【洛谷1967】货车运输(最大生成树+倍增LCA)

    点此看题面 大致题意: 有\(n\)个城市和\(m\)条道路,每条道路有一个限重.多组询问,每次询问从\(x\)到\(y\)的最大载重为多少. 一个贪心的想法 首先,让我们来贪心一波. 由于要求最大载 ...

  6. 货车运输 noip2013 luogu P1967 (最大生成树+倍增LCA)

    luogu题目传送门! 首先,题目让我们求每个货车的最大运输量,翻译一下就是求路径上边权最小的边. 利用一下贪心思想可知,所有货车肯定都会尽量往大的边走. 进一步翻译,即为有一些小边货车根本不会走,或 ...

  7. NOIP2013D1T3货车运输(最大生成树+倍增lca)

    传送门 这道题,先用kruskal求一遍图中的最大生成树. 然后,倍增求lca,求lca的同时求出边权的最小值. #include <cstring> #include <cstdi ...

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

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

  9. Luogu1967 NOIP2013 货车运输 最大生成树、倍增

    传送门 题意:给出一个$N$个节点.$M$条边的图,$Q$次询问,每一次询问两个点之间的所有可行路径中经过的边的边权的最小值中的最大值.$N \leq 10000 , M \leq 50000 , Q ...

随机推荐

  1. 浅谈 foreach 的原理

    package com.shenzhou; import java.util.ArrayList; import java.util.Iterator; import java.util.List; ...

  2. dshow采集过程

    捕捉静态图片常用的filter是Sample Graber filter,它的用法参考手册.然后将捕捉filter的静态PIN连接到Sample Grabber,再将Sample Grabber连接到 ...

  3. mybatisGenerator自动生成pojo、dao、xml文件

    一.简介: mybatisGenerator是一款自动生成文件工具.本文使用idea2017.3.1来进行操作. 二.文件生成之后的项目结构: 三.开始生成步骤: 1.使用idea生成maven的结构 ...

  4. HTML:Registry design.(Include a simple web design use HTML)

    Registry design: I feel a little bored when I design this registry,so T design a simple website all ...

  5. log4j日志输出级别变更

    1.   现阶段log4j日志输出配置 示例:基础服务日志配置 #DEBUG < INFO < WARN < ERROR < FATAL\u65E5\u5FD7\u7684\u ...

  6. ReactiveX 学习笔记(11)对 LINQ 的扩展

    Interactive Extensions(Ix) 本文的主题为对 Ix 库,对 LINQ 的扩展. Buffer Ix.NET Buffer Ix.NET BufferTest Buffer 方法 ...

  7. React/anu实现弹出层2

    这次是使用了一个比较罕见的APIReactDOM.unstable_renderSubtreeIntoContainer,ReactDOM.unstable_renderSubtreeIntoCont ...

  8. avalon2学习教程08插入移除操作

    本节介绍的ms-if指令与ms-visible很相似,都是让某元素"看不见",不同的是ms-visible是通过CSS实现,ms-if是通过移除插入节点实现. ms-if的用法与1 ...

  9. PHP脚本不报错的两点原因

    -------------------------------------------------------------------------------------------------- P ...

  10. mongodb的优缺点

    在这里收集下我自己对Mongodb的一些优缺点方面的认识,或者是通过其它比较可靠的网文上引用或者摘录的作为依据,这个是一个渐进的过程,也是随着我对Mongodb认识的加深而不断扩展的. (1)Mong ...