hszxoj 货车运输 [lca]
题目链接: hszxoj 货车运输
题目描述与思路
- 简化题目:
求 \(x\)到 \(y\) 两点间路径的边权最小值的最大值 - 与之前的最短路最大的不同是这道题是多源最短路,那么 \(spfa\) 就废了,\(Floyd\) 定会 \(TLE\) 所以就需要用新的算法。
- 用 \(lca\) 一定是在树上的,但明显这玩意他既有环又有森林,直接用就会 \(RE\)
- 所以我们需要用到 \(kru\) 重构树
首先展示 \(kru\) 代码
void kru()
{
stable_sort(e+1,e+1+m,cmp);
cnt=n;
for(int i=1;i<=m;i++)
{
int a=find(e[i].x),b=find(e[i].y);
if(a==b) continue;
f[a]=f[b]=++cnt;
g[a].push_back(cnt),g[cnt].push_back(a),
g[b].push_back(cnt),g[cnt].push_back(b);
w[cnt]=e[i].w;
if(++tot==n-1) break;
}
root=n+tot;
}
- 首先排序一下,注意这道题是 \(最大生成树\) ,所以从大到小排序,这样求出来才是最小值的最大值,不然就是最大值的最小值了
- 有三个重要点
- \(1.\) 和正常的最小生成树不同,我们最后只需要输出两点的最近公共祖先的点权,但我们实则求的是对应的边权,就需要将边权转换为点权。不妨将相连的两点 \(x\),\(y\) 中间插入一个点,让这个点的点权为 \(x,y\) 的边权,并使这个点成为 \(x\) 和 \(y\) 的祖先
- 为什么让他成为这两个点的祖先也是显而易见的,我们最后输出最近公共祖先的权值,只有类似这个新点的权值,他才不是 \(0\),看完全部代码后会理解得更清晰

\(变化后是这样,5是新的点,5的权值为1\)

- 为什么让他成为这两个点的祖先也是显而易见的,我们最后输出最近公共祖先的权值,只有类似这个新点的权值,他才不是 \(0\),看完全部代码后会理解得更清晰
- \(2.\) 我们需要搞出来树根 \(root\) 代码里最后有一行 \(root=n+tot\) 为什么这么做呢?他重构树之后显然是有 \(森林\) 的,但他最后一个点不可能是森林(不然他无父无母的都遍历不到这个点),相当重要的,否则只有15分,后面 \(dfs\) 时有用
- \(3.\) 某个脑残问题,看到那个 \(break\) 没有,改成 \(return\) ,\(root\) 就没了 \(\large{qwq}\)
- \(1.\) 和正常的最小生成树不同,我们最后只需要输出两点的最近公共祖先的点权,但我们实则求的是对应的边权,就需要将边权转换为点权。不妨将相连的两点 \(x\),\(y\) 中间插入一个点,让这个点的点权为 \(x,y\) 的边权,并使这个点成为 \(x\) 和 \(y\) 的祖先
- 然后快乐的打完 \(lca\) 就完事了,最后输出两点最近公共祖先的权值即可,题中有一个若两点无法到达,输出 \(-1\) ,判断一下他们两个是不是在一个并查集里,如果不是自然就是不通
- 并查集如果用我这种方法别忘了 \(初始化\),初始化时要搞到 \(n+m\) ,因为我们是要建新的点的不然会炸内存
代码呈上
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=5e5+1;
template<typename Tp> inline void read(Tp&x)
{
x=0;register bool z=1;
register char c=getchar();
for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0;
for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
x=(z?x:~x+1);
}
int n,m,q,cnt,root,tot;
int w[N],f[N],fa[N],dep[N],sz[N],son[N],top[N];
vector<int>g[N];
struct aa{int x,y,w;}e[N];
bool cmp(aa s1,aa s2){return s1.w>s2.w;}
int find(int x)
{
if(f[x]!=x) f[x]=find(f[x]);
return f[x];
}
void kru()
{
stable_sort(e+1,e+1+m,cmp);
cnt=n;
for(int i=1;i<=m;i++)
{
int a=find(e[i].x),b=find(e[i].y);
if(a==b) continue;
f[a]=f[b]=++cnt;
g[a].push_back(cnt),g[cnt].push_back(a),
g[b].push_back(cnt),g[cnt].push_back(b);
w[cnt]=e[i].w;
if(++tot==n-1) break;
}
root=n+tot;
}
void dfs1(int x,int t)
{
fa[x]=t,dep[x]=dep[t]+1,sz[x]=1;
for(int y:g[x])
if(y!=t)
{
dfs1(y,x);
sz[x]+=sz[y];
if(sz[son[x]]<sz[y]) son[x]=y;
}
}
void dfs2(int x,int t)
{
top[x]=t;
if(!son[x]) return ;
dfs2(son[x],t);
for(int y:g[x])
if(y!=son[x]&&y!=fa[x])
dfs2(y,y);
}
int lca(int x,int y)
{
for(;top[x]!=top[y];x=fa[top[x]])
if(dep[top[x]]<dep[top[y]]) swap(x,y);
return dep[x]<dep[y]?x:y;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int x,y;
read(n),read(m);
for(int i=1;i<=n+m;i++) f[i]=i;
for(int i=1;i<=m;i++)
read(e[i].x),read(e[i].y),read(e[i].w);
kru(),dfs1(root,0),dfs2(root,root);
read(q);
while(q--)
read(x),read(y),
cout<<((find(x)!=find(y))?-1:w[lca(x,y)])<<endl;
}
并查集还可以这么打(虽然大多数人都是这么打的)
int find(int x)
{
return (!f[x])?x:f[x]=find(f[x]);
}
这样就不需要初始化了
hszxoj 货车运输 [lca]的更多相关文章
- NOIP2013货车运输[lca&&kruskal]
题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...
- NOIP2013 货车运输 LCA倍增+最大生成树
#include <cstdio> #include <iostream> #include <ctime> #include <vector> #in ...
- 洛谷 P1967 货车运输 LCA + 最小生成树
两点之间边权最大值的最小值一定在图的最小生成树中取到. 求出最小生成树,进行倍增即可. Code: #include<cstdio> #include<algorithm> u ...
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...
- Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...
- 「NOIP2013」「LuoguP1967」货车运输(最大生成树 倍增 LCA
题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...
- 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增
倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...
- codevs3287货车运输(最小生成树+LCA)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 ...
- NOIP 2013 货车运输【Kruskal + 树链剖分 + 线段树 】【倍增】
NOIP 2013 货车运输[树链剖分] 树链剖分 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在 ...
- C++之路进阶——codevs3287(货车运输)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n ...
随机推荐
- 3天上手Ascend C编程丨通过Ascend C编程范式实现一个算子实例
本文分享自华为云社区<3天上手Ascend C编程 | Day2 通过Ascend C编程范式实现一个算子实例>,作者:昇腾CANN . 一.Ascend C编程范式 Ascend C编程 ...
- 为什么大家都在用 WebP?
WebP 是谷歌在 2010 年提出的一种新型的图片格式,放到现在来讲,已经不算是"新"技术了,毕竟已经有了更新的 JPEG XL 和 AVIF .但是在日常工作中,大家时常会碰到 ...
- Journey / Solution Set - 「NOIP-S 2020」「Prob. A-C」
这种东西怎么写啊... Day 1(好像也没有 Day 2 到了 NK 后发现正好可以进门,于是就什么也没有检查的进去了. 进门前问了一下 LYC 之前问过的一个问题,他说没有头绪,然后就没怎么说话了 ...
- TiDB的简单介绍以及进行资源限制的方式与方法
TiDB的简单介绍以及进行资源限制的方式与方法 TiDB的简介 TiDB是一个分布式数据库, 简介为: TiDB 是一个开源的分布式关系型数据库,它兼具了分布式数据库的水平扩展性和传统关系型数据库的 ...
- TTS背后的技术原理——前端和后端系统
就解锁了一个温柔又风趣的「女朋友」萨曼萨.不过,在现实生活中,和语音助手谈恋爱还是一件十分遥远的事情--刨去现阶段的语音助手们双商水平还有限,语音助手的语言表达能力还远远达不到我们理想状态. ...
- [ABC310D] Peaceful Teams 题解
Peaceful Teams 题目大意 将 \(n\) 个人分成 \(T\) 组,要求每组不能包含敌对的人,问有多少种分法. 思路分析 注意到 \(n,T\) 均很小,考虑爆搜. 注意到直接枚举会枚举 ...
- 关于通过StringTemplate模板生成xml转成excel后office无法打开的问题解决
说明:本人最近在着手实现导出日志数据,由于日志数据过多,在网上查找java 导出大量数据到excel的例子. 后发现园子里某位老哥通过StringTemplate模板生成excel格式的xml,这个思 ...
- 如何打开关闭Edge鼠标手势
概述 今天突然发现edge有了一个鼠标手势,用起来不是很适应,所以决定将其关掉. 操作步骤 点击edge右上角的三个点 在下拉菜单中选择设置 点开设置之后出现如图所示的界面,然后选择外观 往下面拉页面 ...
- 数组操作 filter和find
现在有个需求: 后端给一个list过来,1-4,有就显示,没有前面四个card就空着,从第五个开始,有数据就循环出来,区别他们的kind字段. 这里想了很久怎么写,最后决定,洗数据. 就是从给给的数据 ...
- Go 接口:nil接口为什么不等于nil?
Go 接口:nil接口为什么不等于nil? 本文主要内容:深入了解接口类型的运行时表示层. 目录 Go 接口:nil接口为什么不等于nil? 一.Go 接口的地位 二.接口的静态特性与动态特性 2.1 ...