TZOJ 4848 货车运输(最大生成树+倍增lca)
描述
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)的更多相关文章
- $Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$
$Luogu$ $Sol$ 首先当然是构建一棵最大生成树,然后对于一辆货车的起点和终点倍增跑$lca$更新答案就好.记得预处理倍增的时候不仅要处理走了$2^i$步后是那个点,还有这中间经过的路径权值的 ...
- 【NOIP2013】货车运输 最大生成树+倍增
题目大意:给你一张n个点m条边的图,有q次询问,每次让你找出一条从x至y的路径,使得路径上经过的边的最小值最大,输出这个最大的最小值. 显然,经过的路径必然在这张图的最大生成树上. 我们求出这个图的最 ...
- 「NOIP2013」「LuoguP1967」货车运输(最大生成树 倍增 LCA
题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...
- 货车运输(最大生成树+倍增LCA)
看到第一篇题解的神奇码风--我决定发一篇码风正常的题解造福人类 这题的做法也非常经典,最大生成树\(+LCA\),相当于先贪心一下,在LCA的时候记录一下当前最小的边权 顺便吐槽一下最后一个测试点: ...
- 【洛谷1967】货车运输(最大生成树+倍增LCA)
点此看题面 大致题意: 有\(n\)个城市和\(m\)条道路,每条道路有一个限重.多组询问,每次询问从\(x\)到\(y\)的最大载重为多少. 一个贪心的想法 首先,让我们来贪心一波. 由于要求最大载 ...
- 货车运输 noip2013 luogu P1967 (最大生成树+倍增LCA)
luogu题目传送门! 首先,题目让我们求每个货车的最大运输量,翻译一下就是求路径上边权最小的边. 利用一下贪心思想可知,所有货车肯定都会尽量往大的边走. 进一步翻译,即为有一些小边货车根本不会走,或 ...
- NOIP2013D1T3货车运输(最大生成树+倍增lca)
传送门 这道题,先用kruskal求一遍图中的最大生成树. 然后,倍增求lca,求lca的同时求出边权的最小值. #include <cstring> #include <cstdi ...
- 【NOIP2013】货车运输 最大生成树+LCA
题目描述 AA国有nn座城市,编号从 1到n,城市之间有m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重 ...
- Luogu1967 NOIP2013 货车运输 最大生成树、倍增
传送门 题意:给出一个$N$个节点.$M$条边的图,$Q$次询问,每一次询问两个点之间的所有可行路径中经过的边的边权的最小值中的最大值.$N \leq 10000 , M \leq 50000 , Q ...
随机推荐
- PowerDesigner 把Comment写到name中 和把name写到Comment中 pd7以后版本可用
在使用PowerDesigner对数据库进行概念模型和物理模型设计时,一般在NAME或Comment中写中文,在Code中写英文.Name用来显 示,Code在代码中使用,但Comment中的文字会保 ...
- day09-数据库插入中文报错
在向数据库表中插入中文时一直报错 MySQL的默认编码是Latin1,不支持中文,要支持中文需要把数据库的默认编码修改为gbk或者utf8. 1.需要以root用户身份登陆才可以查看数据库编码方式(以 ...
- 使用pt-table-checksum及pt-table-sync校验复制一致性
一.简介 pt-table-checksum是percona-toolkit系列工具中的一个, 可以用来检测主. 从数据库中数据的一致性.其原理是在主库上运行, 对同步的表进行checksum, 记录 ...
- mysql 的REPLAYCE语句
MySQL数据库insert和update语句引:用于操作数据库的SQL一般分为两种,一种是查询语句,也就是我们所说的SELECT语句,另外一种就是更新语句,也叫做数据操作语句.言外之意,就是对数 ...
- week5 04 npm run build
上期 我们完成了nodeserver的创建 用的是express genrealtor那个工具 我们在server端执行 起来了 然后我们改一下 删一下 我们觉着暂时没用的东西 首先去app.js程序 ...
- Ubuntu中更改所有子文件和子目录所有者权限
转自:http://www.linuxidc.com/Linux/2015-03/114695.htm Ubuntu中有两个修改命令可以用到,「change mode」&「change own ...
- SPSS-判别分析
判别分析 判别分析是一种有效的对个案进行分类分析的方法.和聚类分析不同的是,判别分析时组别的特征已知. 定义:判别分析先根据已知类别的事物的性质,利用某种技术建立函数式,然后对未知类别的新事物进 行判 ...
- 学习-HTML5
@@ 学习HTML5发现对我们开发工作者来说要方便很多,它现在还在发展阶段,在未来肯定会是主流. 我们知道HTML5目的是取代HTML4.01和XHTML1.0标准,他希望能够减少互联网富应用(RIA ...
- maven(二)基于intellij idea搭建ssm的maven项目结构
项目配置文件整合步骤 1.这里使用maven来引入项目所需要的jar包,所以也就不需要手动来管理jar包了. pom.xml 配置模板如下: <project xmlns="http: ...
- CSS同时选择器
[CSS同时选择器] 同一个div拥有多个class时,我们可以作多个class作为组合来选择对象.方法就是将多个.className直接连接在一起(中间不能有空格). <p class=&qu ...