P1967 货车运输 题解
博客园同步
原题链接
简要题意:
给定一个无向图,若干组询问问 x → y x \rightarrow y x→y 所有路径上最小权值的最大值。
算法一
对于 60 % 60\% 60% 的数据, 1 ≤ n < 1 0 3 , 1 ≤ m < 5 × 1 0 4 , 1 ≤ q < 1 0 3 1 \le n < 10^3,1 \le m < 5\times 10^4,1 \le q< 10^3 1≤n<103,1≤m<5×104,1≤q<103
如果您有网络流板子的话,可以认为,本题是 给定网络图,若干组流量询问,直接 ISAP \text{ISAP} ISAP 乱跑就可以得到 O ( q n m ) O(qnm) O(qnm) 的优秀时间,轻松得到 60 p t s 60pts 60pts 及以上。(网络流算法时间跑不满)
说句闲话:这题网络流怎么优化
时间复杂度: O ( q n m ) O(qnm) O(qnm). 期望得分: 60 p t s 60pts 60pts. 实际得分 100pts
算法二
对于 100 % 100\% 100% 的数据, 1 ≤ n < 1 0 4 , 1 ≤ m < 5 × 1 0 4 , 1 ≤ q < 3 × 1 0 4 , 0 ≤ z ≤ 1 0 5 1 \le n < 10^4 , 1 \le m < 5\times 10^4 , 1 \le q< 3\times 10^4 , 0 \le z \le 10^5 1≤n<104,1≤m<5×104,1≤q<3×104,0≤z≤105.
首先,我们考虑的是,如果, x → u ( w 1 ) x \rightarrow u (w_1) x→u(w1) , u → v ( w 2 ) u \rightarrow v (w_2) u→v(w2) ,与 x → v ( w 3 ) x \rightarrow v (w_3) x→v(w3) 同时存在的话,如果 min ( w 1 , w 2 ) ≤ w 3 \min(w_1,w_2) \leq w_3 min(w1,w2)≤w3,可以直接把 w 3 w_3 w3 扔掉;走的时候肯定是走 x → w → v x \rightarrow w \rightarrow v x→w→v 了。
那么,我们得到了网络流的贪心算法 显然,我们需要对每一组 x → y x \rightarrow y x→y 都把这样的 废边 去掉。
嗯?所以我们要把所有 x → y x \rightarrow y x→y 的最大路径取出来,对吧?
那么,最大生成树 就映入我们眼帘:显然这是 最大生成树重构图 !
求最大生成树并只留下这个树上的边(重构),那么 x → y x \rightarrow y x→y 肯定是最大路径(不然肯定换边了)。
那么如何应对询问?显然,我们在 树上求两点路径 用 LCA \text{LCA} LCA 操作即可。
注意细节。
时间复杂度: O ( n log n + q log n + m ) O(n \log n + q \log n + m) O(nlogn+qlogn+m).
实际得分: 100 p t s 100pts 100pts.
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;const int N=1e5+1;inline int read(){char ch=getchar(); int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}struct EE1 {int x,y,dis;} E1[N];
struct E2 {int to,nxt,w;} E2[N];
int head[N],n,m,f[N],deep[N],cnt,q;
int fa[N][21],w[N][21]; bool vis[N];inline void add(int u,int v,int w) {if(u==v) return;E2[++cnt].nxt=head[u];E2[cnt].to=v; E2[cnt].w=w;head[u]=cnt; return;
}inline int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
inline bool cmp(EE1 x,EE1 y) {return x.dis>y.dis;}inline void kruskal() {sort(E1+1,E1+1+m,cmp);for(int i=1;i<=n;i++) f[i]=i;for(int i=1;i<=m;i++) {int u=E1[i].x,v=E1[i].y,w=E1[i].dis;if(find(u)-find(v)) {f[find(u)]=find(v);add(u,v,w); add(v,u,w);} }
} //最大生成树模板inline void dfs(int u) {vis[u]=1;for(int i=head[u];i;i=E2[i].nxt) {int v=E2[i].to,t=E2[i].w;if(vis[v]) continue;deep[v]=deep[u]+1;fa[v][0]=u; w[v][0]=t;dfs(v);} return;
} //预处理父亲inline int LCA(int x,int y) {if(find(x)-find(y)) return -1;int ans=INT_MAX;if(deep[x]>deep[y]) swap(x,y);for(int i=20;i>=0;i--)if(deep[fa[y][i]]>=deep[x]) ans=min(ans,w[y][i]),y=fa[y][i]; //调整深度if(x==y) return ans;for(int i=20;i>=0;i--)if(fa[x][i]-fa[y][i]) {ans=min(ans,min(w[x][i],w[y][i]));x=fa[x][i]; y=fa[y][i];} //一起跳return min(ans,min(w[x][0],w[y][0])); //最后答案
}int main() {n=read(),m=read();for(int i=1;i<=m;i++) {int u=read(),v=read(),w=read();
// add(u,v,w); add(v,u,w);E1[i].x=u; E1[i].y=v; E1[i].dis=w;} kruskal();for(int i=1;i<=n;i++)if(!vis[i]) {deep[i]=1; dfs(i);fa[i][0]=i; w[i][0]=INT_MAX;} q=read();for(int i=1;i<=20;i++)for(int j=1;j<=n;j++) {fa[j][i]=fa[fa[j][i-1]][i-1]; //fa[j][i] 为 j 向上走 2^i 个节点到达的节点w[j][i]=min(w[j][i-1],w[fa[j][i-1]][i-1]); //w[j][i] 为 j 向上走 2^i 个节点经过路径的权值最小值} while(q--) printf("%d\n",LCA(read(),read())); return 0;
}
P1967 货车运输 题解相关推荐
- 【杂题总汇】NOIP2013(洛谷P1967) 货车运输
[洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...
- 货车运输题解 最大生成树+lca
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条 ...
- noip 2013 洛谷 P1967 货车运输
题目:货车运输 大致题意: 给出一张无向带权图,对于m个询问(X,Y),要求找出X到Y的一条路径使得路径上的最小边权最大,并输出这个最小边权. 思路: 可以看出,X到Y的满足条件的路径一定在原图的最大 ...
- java动态规划货车运输,题解 P1967 【货车运输】
树链剖分+线段树 思路 貌似题解里没有树链剖分和线段树的,贡献一发. 首先明确题目要求:一辆车走某条路从x城到y城的边权最小值 我们把要求分开来看: 从x城到y城:我们需要走的路径将两点联通 边权最小 ...
- luogu p1967 货车运输
题意:有n座城市,其间有m条道路相连,构成无向图,图中可能存在孤点.每条道路有一个限重值,货车走这条道路时所载货物的重量不应超过限重值.有q次询问,每次询问给出两个城市,问从城市1到城市2之间货车的最 ...
- 洛谷 P1967货车运输 并查集+贪心 不需要用LCA!
题目链接 题目链接 题解 要求所有的路径中最小边长的最大值! 我们贪心的加边,依照边从大往小的方式往里添加,然后合并并查集. 每次当查询分布在两个待合并的并查集的时候,当前的边长就是这次查询的答案. ...
- P1967 货车运输
传送门 算法:最大生成树 & LCA 题目要求两点之间最小边权 的最大值.. 就是两点之间有多条路径,每条路径有一个 最小边权 要找到最大的 最小边权 考虑kruskal算法的过程 如果我们 ...
- P1967 货车运输( 最大生成树+LCA or Kruskal重构树)
至于为什么要用最大生成树!? 理由:因为问最大载重,如果要加大载重的话,对于选择的路肯定权重越大越好,所以贪心地想,得用到最大生成树.然后两点之间的最大载重用LCA去寻找就可以了. 最大生成树+LCA ...
- 【题解】【洛谷 P1967】 货车运输
目录 洛谷 P1967 货车运输 原题 题解 思路 代码 洛谷 P1967 货车运输 原题 题面请查看洛谷 P1967 货车运输. 题解 思路 根据题面,假设我们有一个普通的图: 作图工具:Graph ...
最新文章
- oracle数据库如何写翻页_ORACLE数据库分页查询/翻页 最佳实践
- 深入理解linux系统的目录结构
- android调试神器Stetho
- mysql导出表结构 创建_mysql如何导出表结构为文本文件
- 如何使用notepad运行python程序
- 一ElasticSearch安装启动
- #苹果maccmsv10# redis memcached 缓存的若干问题解决
- Java使用lambda进行分页,SpringBoot(八):整合mybatis,通用mapper,分页插件,lambda,Logger,junit用法...
- axis1 c# 接口 调用_java调用c#的Webservice接口数据报错
- android中的handler例
- 常见数通设备镜像制作模板
- 频率域滤波去除周期性噪声
- python opencv读大华摄像头视频流实时移动侦测运动检测截图拍照保存
- Android图标下载网站
- 用python批量发送短信_Python批量发短信
- oracle 验证 lob 坏块,Oracle LOB坏块处理
- verilog赋多位值_verilog中的default应该赋什么样的值
- awk】1-awk基础篇(又名UNIX.Shell.awk)
- Leetcode 2020/12/03打卡 204计算质数(简单)
- 湖南大学计算机考研群2021,湖南大学2021年硕士研究生拟录取名单公示
热门文章
- A Cuboid CNN Model with an Attention Mechanism for Skeleton-based Action Recognition---论文理解
- android studio记账,Android Studio--家庭记账本(五)
- php中status,phpfpm status状态说明
- 谷歌大动作:最高优先级项目曝光,下一代AI搜索,剑指ChatGPT!
- 封神台 第二章 绕过WAF
- 查java使用的内存_Java内存占用排查的方法
- 剖析CPU温度监控技术
- 打通apk到hal层
- 根据地理位置多语言切换(1)- 获取地理位置信息
- APM2.8自驾仪入门手册(AMOV AUTO)