【Luogu P1967】货车运输
Luogu P1967
题目大意:给定一张图和q个询问,询问x节点和y节点的路径之间最小边权最大可以是多少。
可以发现对于一条边\(E(x,y)\),如果x到y有另一条路径且最小边权大于\(E(x,y)\),那么这条边完全可以不考虑了。
综上所述,我们可以考虑对这张图使用Kruskal构建最大生成树。
那么两个点之间的路径就可以使用倍增LCA来求解了。
注意:原图可能并不连通,构成的可能是一个森林,所以要加入特判。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxm=50005,maxn=10005;
struct data
{
int sta,val,to,next;
bool operator <(const data&x) const
{
return val>x.val;
}
}e[2*maxm],edge[2*maxm];
int cnt,head[maxn],n,q,m,x,y,ans,z,fa[maxn],f[maxn][32],val[maxn][32],d[maxn],lg[maxn];
void add(int u,int v,int w)
{
e[++cnt].sta=u;
e[cnt].to=v;
e[cnt].val=w;
}
int getf(int v)
{
if (fa[v]!=v) return fa[v]=getf(fa[v]);
return fa[v];
}
inline void merge(int x,int y)
{
fa[getf(x)]=getf(y);
}
inline bool check(int x,int y)
{
return fa[getf(x)]==fa[getf(y)];
}
void dfs(int now,int fat)
{
f[now][0]=fat;d[now]=d[fat]+1;
for (int i=1;i<=lg[d[now]];i++)
{
f[now][i]=f[f[now][i-1]][i-1];
val[now][i]=min(val[now][i-1],val[f[now][i-1]][i-1]);
//记录路径上的最小边权,注意理解。
}
for (int i=head[now];i;i=edge[i].next)
{
if (edge[i].to==fat) continue;
val[edge[i].to][0]=edge[i].val;
dfs(edge[i].to,now);
}
}
int lca(int x,int y)
{
if (!check(x,y)) return -1;
if (d[x]<d[y]) swap(x,y);
ans=2147483647;
/*注意这里不能写ans=min(val[x][0],val[y][0]);这两条边不一定是必选的。
因为y可能本身就是lca(x,y)*/
while (d[x]>d[y])
{
ans=min(ans,val[x][lg[d[x]-d[y]]-1]);//注意顺序,更新x之前先更新最小边权。
x=f[x][lg[d[x]-d[y]]-1];
}
if (x==y) return ans;
for (int i=lg[d[x]]-1;i>=0;i--)
if (f[x][i]!=f[y][i])
{
ans=min(ans,min(val[x][i],val[y][i]));
x=f[x][i];y=f[y][i];
//同样注意顺序
}
return ans=min(ans,min(val[x][0],val[y][0]));
}
int main()
{
memset(val,0x3f,sizeof(val));
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
for (int i=1;i<=n;i++) fa[i]=i;
sort(e+1,e+1+cnt);
int tmpcnt=cnt;
cnt=0;
for (int i=1;i<=tmpcnt;i++)
if (!check(e[i].sta,e[i].to))
{
merge(e[i].sta,e[i].to);
edge[++cnt].to=e[i].to;
edge[cnt].val=e[i].val;
edge[cnt].next=head[e[i].sta];
head[e[i].sta]=cnt;
edge[++cnt].to=e[i].sta;
edge[cnt].val=e[i].val;
edge[cnt].next=head[e[i].to];
head[e[i].to]=cnt;
}
for (int i=1;i<=n;i++) lg[i]=lg[i-1]+(1<<lg[i-1]==i);
for (int i=1;i<=n;i++)
if (!d[i]) dfs(i,0);
scanf("%d",&q);
for (int i=1;i<=q;i++)
{
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}
【Luogu P1967】货车运输的更多相关文章
- Luogu P1967 货车运输(Kruskal重构树)
P1967 货车运输 题面 题目描述 \(A\) 国有 \(n\) 座城市,编号从 \(1\) 到 \(n\) ,城市之间有 \(m\) 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 \ ...
- LUOGU P1967 货车运输(最大生成树+树剖+线段树)
传送门 解题思路 货车所走的路径一定是最大生成树上的路径,所以先跑一个最大生成树,之后就是求一条路径上的最小值,用树剖+线段树,注意图可能不连通.将边权下放到点权上,但x,y路径上的lca的答案不能算 ...
- Luogu P1967 货车运输
qwq 这题是知道了正解做法才写的.. 求每两点间最小权值最大的路径,本来我以为要每个点都跑一遍dij(?),后来意识到生成树好像是用来找这个的( ´▽`) 然后我问dtxdalao对不对,他说“我记 ...
- Luogu P1967 货车运输 倍增+最大生成树
看见某大佬在做,决定补一发题解$qwq$ 首先跑出最大生成树(注意有可能不连通),然后我们要求的就是树上两点间路径上的最小边权. 我们用倍增的思路跑出来$w[u][j]$,表示$u$与的它$2^j$的 ...
- 洛谷 P1967 货车运输
洛谷 P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在 ...
- P1967 货车运输
P1967 货车运输最大生成树+lca+并查集 #include<iostream> #include<cstdio> #include<queue> #inclu ...
- kruskal - 倍增 - 并查集 - Luogu 1967 货车运输
P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过 ...
- 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增
倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...
- 【杂题总汇】NOIP2013(洛谷P1967) 货车运输
[洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...
- [luogu 1967]货车运输
货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情 ...
随机推荐
- 微信公众号 访问403问题,样式错乱,js失效
我服了,还是那个微信公众号小项目. 这个项目用的是ssm+velocity 问题的是,有时候页面加载会乱,js,css都加载不出来. 这个问题也是很久了,前几天开会,那个甲方医院很不开心,说是要找下家 ...
- 通过FeignClient接收shaded的javabean的JSON序列化
问题说明 最近做了关于flink的需求. 现在需要通过HTTP访问FLINK的 RESTAPI, rest 接口的JSON 非常庞大而复杂. 那么怎么去完整的接收数据呢? 方法一就是手写部分需要的Ja ...
- 分享一次大厂的技术面试通过,却因学历被拒发 offer 的悲惨经历
概述 今天心情很down,快周末了,说点不开心的事情给大家开心一下,上周面试心仪已久的大厂,技术面很顺利的通过一面/二面/三面,最后到HR面也很顺利,然后被问到学历(自考本科)后,HR 语气发生一些转 ...
- 变量 + 数据类型(数字 + 字符串)(day03整理)
目录 一.上节课回顾 四 编程语言分类 (一) 机器语言 (二)汇编语言 (三) 高级语言 (四) 网络瓶颈效应 五.执行python程序两种方式 (一) 交互式(jupytre) (二) 命令行式( ...
- 设计模式(二十一)Proxy模式
在面向对象编程中,“本人”和“代理人”都是对象.如果“本人”对象太忙了,有些工作无法自己亲自完成,就将其交给“代理人”对象负责. 示例程序的类图. 示例程序的时序图.从这个时序图可以看出,直到调用pr ...
- Mac高效开发之iTerm2、Prezto和Solarized主题
本文首发于个人网站:Mac高效开发之iTerm2.Prezto和Solarized主题 工欲善其事必先利其器,作为开发,我追求极致的高效,因此会在很多细节上追求效率,例如:命令行窗口敲命令的时候,如果 ...
- 构建企业级数据湖?Azure Data Lake Storage Gen2实战体验(下)
相较传统的重量级OLAP数据仓库,“数据湖”以其数据体量大.综合成本低.支持非结构化数据.查询灵活多变等特点,受到越来越多企业的青睐,逐渐成为了现代数据平台的核心和架构范式. 作为微软Azure上最新 ...
- 使用grep过滤make的输出内容
make的输出内容其实分为两种,有些是到标准输出,有些是到标准错误,由于标准输出和标准错误默认都是屏幕,所以平时区分不出来, 实际上一般是error和warning信息到标准错误,其余的到标准输出. ...
- 服务器配置:ECS+Nginx+uWSGI+Flask——各部分详细介绍
希望在阿里云ECS上搭建一个flask框架的web应用,经典的形式便是flask+uWSGI+nginx模式 服务器:CentOS 7.3 python版本:3.8.0 先贴一张全局图,这张图很清楚的 ...
- podman初试-和docker对比
podman初试-和docker对比 1,什么是docker? Docker 是一个开源的应用容器引擎,属于 Linux 容器的一种封装,Docker 提供简单易用的容器使用接口,让开发者可以打包他们 ...