博客园同步

原题链接

简要题意:

给定一个无向图,若干组询问问 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 货车运输 题解相关推荐

  1. 【杂题总汇】NOIP2013(洛谷P1967) 货车运输

    [洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...

  2. 货车运输题解 最大生成树+lca

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条 ...

  3. noip 2013 洛谷 P1967 货车运输

    题目:货车运输 大致题意: 给出一张无向带权图,对于m个询问(X,Y),要求找出X到Y的一条路径使得路径上的最小边权最大,并输出这个最小边权. 思路: 可以看出,X到Y的满足条件的路径一定在原图的最大 ...

  4. java动态规划货车运输,题解 P1967 【货车运输】

    树链剖分+线段树 思路 貌似题解里没有树链剖分和线段树的,贡献一发. 首先明确题目要求:一辆车走某条路从x城到y城的边权最小值 我们把要求分开来看: 从x城到y城:我们需要走的路径将两点联通 边权最小 ...

  5. luogu p1967 货车运输

    题意:有n座城市,其间有m条道路相连,构成无向图,图中可能存在孤点.每条道路有一个限重值,货车走这条道路时所载货物的重量不应超过限重值.有q次询问,每次询问给出两个城市,问从城市1到城市2之间货车的最 ...

  6. 洛谷 P1967货车运输 并查集+贪心 不需要用LCA!

    题目链接 题目链接 题解 要求所有的路径中最小边长的最大值! 我们贪心的加边,依照边从大往小的方式往里添加,然后合并并查集. 每次当查询分布在两个待合并的并查集的时候,当前的边长就是这次查询的答案. ...

  7. P1967 货车运输

    传送门 算法:最大生成树 & LCA 题目要求两点之间最小边权  的最大值.. 就是两点之间有多条路径,每条路径有一个 最小边权 要找到最大的 最小边权 考虑kruskal算法的过程 如果我们 ...

  8. P1967 货车运输( 最大生成树+LCA or Kruskal重构树)

    至于为什么要用最大生成树!? 理由:因为问最大载重,如果要加大载重的话,对于选择的路肯定权重越大越好,所以贪心地想,得用到最大生成树.然后两点之间的最大载重用LCA去寻找就可以了. 最大生成树+LCA ...

  9. 【题解】【洛谷 P1967】 货车运输

    目录 洛谷 P1967 货车运输 原题 题解 思路 代码 洛谷 P1967 货车运输 原题 题面请查看洛谷 P1967 货车运输. 题解 思路 根据题面,假设我们有一个普通的图: 作图工具:Graph ...

最新文章

  1. oracle数据库如何写翻页_ORACLE数据库分页查询/翻页 最佳实践
  2. 深入理解linux系统的目录结构
  3. android调试神器Stetho
  4. mysql导出表结构 创建_mysql如何导出表结构为文本文件
  5. 如何使用notepad运行python程序
  6. 一ElasticSearch安装启动
  7. #苹果maccmsv10# redis memcached 缓存的若干问题解决
  8. Java使用lambda进行分页,SpringBoot(八):整合mybatis,通用mapper,分页插件,lambda,Logger,junit用法...
  9. axis1 c# 接口 调用_java调用c#的Webservice接口数据报错
  10. android中的handler例
  11. 常见数通设备镜像制作模板
  12. 频率域滤波去除周期性噪声
  13. python opencv读大华摄像头视频流实时移动侦测运动检测截图拍照保存
  14. Android图标下载网站
  15. 用python批量发送短信_Python批量发短信
  16. oracle 验证 lob 坏块,Oracle LOB坏块处理
  17. verilog赋多位值_verilog中的default应该赋什么样的值
  18. awk】1-awk基础篇(又名UNIX.Shell.awk)
  19. Leetcode 2020/12/03打卡 204计算质数(简单)
  20. 湖南大学计算机考研群2021,湖南大学2021年硕士研究生拟录取名单公示

热门文章

  1. A Cuboid CNN Model with an Attention Mechanism for Skeleton-based Action Recognition---论文理解
  2. android studio记账,Android Studio--家庭记账本(五)
  3. php中status,phpfpm status状态说明
  4. 谷歌大动作:最高优先级项目曝光,下一代AI搜索,剑指ChatGPT!
  5. 封神台 第二章 绕过WAF
  6. 查java使用的内存_Java内存占用排查的方法
  7. 剖析CPU温度监控技术
  8. 打通apk到hal层
  9. 根据地理位置多语言切换(1)- 获取地理位置信息
  10. APM2.8自驾仪入门手册(AMOV AUTO)