【题解】【洛谷 P1967】 货车运输
目录
- 洛谷 P1967 货车运输
- 原题
- 题解
- 思路
- 代码
洛谷 P1967 货车运输
原题
题面请查看洛谷 P1967 货车运输。
题解
思路
根据题面,假设我们有一个普通的图:
作图工具:Graph Editor
考虑从顶点\(1\)走到顶点\(3\):
路径\(1 \to 3\)(最大运货量为\(1\));
路径\(1 \to 2 \to 3\)(最大运货量为\(3\),更优)。
所以我们可以删掉\(1 \to 3\)这条边,形成了一棵树,通过多次观察发现,这是一颗原图的最大生成树。
问题就被转化成了求最大生成树和在树上解决原问题。
代码
求最大生成树:我们使用\(\text{Kruskal}\)算法;
在树上解决原问题比较简单,我们只需要通过最近公共祖先(倍增法求解)进行求解即可。
代码如下:
#include <algorithm>
#include <cstdio>
using std::sort;
#define INF 0X3F3F3F3F
#define min(a, b) ((a) < (b) ? (a) : (b))struct Tree
{bool vis[10001];int cnt, head[10001], to[20001], w[20001], Next[20001];int dep[10001], fa[10001][21], W[10001][21];void DFS(int);void Add_Edge(int, int, int);void LCA_Init(void);int LCA(int, int);
};struct Graph
{struct Kruskal{struct Edge{int f, t, val;bool operator<(const Edge &a) const{return val > a.val;}};struct Union_Find{int ID[10001];void Init(void);void connect(int, int);bool search(int, int);int find(int);};Union_Find B;Edge E[50001];void kruskal(void);};int n, m;Kruskal K;void Read(void);
};int q;
Tree T;
Graph G;int main(void)
{G.Read();G.K.B.Init();G.K.kruskal();T.LCA_Init();scanf("%d", &q);while (q--){static int x, y;scanf("%d%d", &x, &y);printf("%d\n", T.LCA(x, y));}return 0;
}void Tree::Add_Edge(int f, int t, int val)
{Next[++cnt] = head[f];to[cnt] = t;w[cnt] = val;head[f] = cnt;return;
}void Tree::DFS(int ID)
{register int i, To;vis[ID] = true;for (i = head[ID]; i; i = Next[i]){To = to[i];if (vis[To])continue;dep[To] = dep[ID] + 1;fa[To][0] = ID;W[To][0] = w[i];DFS(To);}return;
}void Tree::LCA_Init(void)
{register int i, j;for (i = 1; i <= G.n; ++i)if (!vis[i]){dep[i] = 1;DFS(i);fa[i][0] = i;W[i][0] = INF;}for (i = 1; i <= 20; ++i)for (j = 1; j <= G.n; ++j){fa[j][i] = fa[fa[j][i - 1]][i - 1];W[j][i] = min(W[j][i - 1], W[fa[j][i - 1]][i - 1]);}return;
}int Tree::LCA(int x, int y)
{if (!G.K.B.search(x, y))return -1;register int i, ans = INF;if (dep[x] > dep[y]){int temp = x;x = y;y = temp;}for (i = 20; i >= 0; --i)if (dep[fa[y][i]] >= dep[x]){ans = min(ans, W[y][i]);y = fa[y][i];}if (x == y)return ans;for (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];}ans = min(ans, min(W[x][0], W[y][0]));return ans;
}void Graph::Kruskal::Union_Find::Init(void)
{register int i;for (i = 1; i <= G.n; ++i)ID[i] = i;return;
}void Graph::Kruskal::Union_Find::connect(int a, int b)
{register int ra = find(a), rb = find(b);if (ra != rb)ID[rb] = ra;return;
}bool Graph::Kruskal::Union_Find::search(int a, int b)
{return find(a) == find(b);
}int Graph::Kruskal::Union_Find::find(int x)
{if (x == ID[x])return x;elsereturn ID[x] = find(ID[x]);
}void Graph::Kruskal::kruskal(void)
{register int i, cnt = 0;sort(E + 1, E + G.m + 1);for (i = 1; i <= G.m && cnt < G.n - 1; ++i){if (!B.search(E[i].f, E[i].t)){B.connect(E[i].f, E[i].t);++cnt;T.Add_Edge(E[i].f, E[i].t, E[i].val);T.Add_Edge(E[i].t, E[i].f, E[i].val);}}return;
}void Graph::Read(void)
{register int i;scanf("%d%d", &n, &m);for (i = 1; i <= m; ++i)scanf("%d%d%d", &K.E[i].f, &K.E[i].t, &K.E[i].val);return;
}
转载于:https://www.cnblogs.com/Lu-Anlai/p/Luogu_P1967_Solution.html
【题解】【洛谷 P1967】 货车运输相关推荐
- 【杂题总汇】NOIP2013(洛谷P1967) 货车运输
[洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...
- noip 2013 洛谷 P1967 货车运输
题目:货车运输 大致题意: 给出一张无向带权图,对于m个询问(X,Y),要求找出X到Y的一条路径使得路径上的最小边权最大,并输出这个最小边权. 思路: 可以看出,X到Y的满足条件的路径一定在原图的最大 ...
- 洛谷 P1967货车运输 并查集+贪心 不需要用LCA!
题目链接 题目链接 题解 要求所有的路径中最小边长的最大值! 我们贪心的加边,依照边从大往小的方式往里添加,然后合并并查集. 每次当查询分布在两个待合并的并查集的时候,当前的边长就是这次查询的答案. ...
- 洛谷1967货车运输
题目:https://www.luogu.org/problemnew/show/P1967 倍增LCA裸题.用了在线.还有离线O(n)做法.树链剖分做法,暂不管了. (自己程序的)坑点:1.xnt从 ...
- 洛谷T1967 货车运输 Kruskal最大生成树倍增LCA
这题的题意是:对于每组x.y,求x到y路径上最小边权的最大值. 于是可以使用最大生成树,因为最大生成树满足性质:生成树中最小边权最大,且任意两点间路径上最小边权最大. 有了树之后,要求路径,那就要考虑 ...
- 题解 洛谷P1365 WJMZBMR打osu! / Easy
题解 洛谷P1365 WJMZBMR打osu! / Easy Date 2019.7.28 题目大意 给出一个长度为n的由o,x,?组成的字符串,对于每连续的a个o,就有a2分.同时,对于任意的?,有 ...
- 【洛谷P1967】[NOIP2013]货车运输
货车运输 题目链接 显然,从一点走到另一点的路径中,最小值最大的路径一定在它的最大生成树上 所以要先求出最大生成树,再在生成树上找最近公共祖先,同时求出最小值. 1 #include<iostr ...
- python刷题 NOI题库 python题解 洛谷、牛客网、AcWing 刷题等
NOI题库 python题解-2022.01.07整理(1.1-1.3) NOI题库 python题解-2022.01.07整理(1.1-1.3)_dllglvzhenfeng的博客-CSDN博客 N ...
- 题解 洛谷P4473 【[国家集训队]飞飞侠】
这道题今天我们考试考到了,第三题,最后只剩半小时了,随便打了个暴搜,最后竟然还没调完QAQ,我竟然连暴力都不会打了 咳咳,不扯了,下面开始说这道题的做法 由于N和M都不大于150最容易想到的是Floy ...
最新文章
- 做好自己,一切都是最好的安排
- 服务器dbback文件夹,怎么让SQL 2000定时复制备份数据库到局域网中的指定电脑上? - SQL Server论坛 - 51CTO技术论坛_中国领先的IT技术社区...
- jittor和pytorch生成网络对比之softmax_gan
- python3.8使用requests_python3.8.1 入门基础学习 之 【 requests 基础学习,python3爬虫必备基础】...
- 为什么说能源管理是分布式光伏发电的突破口?
- [BZOJ 1046] [HAOI2007] 上升序列 【DP】
- java如何实现e的次方_Java开发如何更改MySQL数据库datadir目录之MySQL数据库索引实现...
- Java LinkedList对象的clone()方法和示例
- 服务器本地文件传输,服务器 本地 文件传输
- 安装scrapy 出现Failed building wheel for Twisted(总是显示此错误)解决办法
- 字节大牛耗时八个月又一力作,原理+实战讲解
- Appium 控件定位链接整理(appiumdriver)
- 【luogu T34117 打油门】 题解
- c++ 类与默认函数、包括构造函数和析构函数的特点
- 《上海悠悠接口自动化平台》-3.流程性用例,有关联的接口如何写?
- 超详细陀螺仪MPU6050模块输出姿态角(有完整版源码)
- matlab 线性拟合polyfit_matlab如何做线性拟合
- java.lang.StringIndexOutOfBoundsException
- python人脸特征提取_Python实现识别人脸特征并打印出来
- 使用 kubeadm 初始化 worker节点出现 not ready 故障
热门文章
- Jerry 2016年5月20日到5月23日的学习笔记
- 利用Docker volume修改Nginx Docker镜像里index.html
- 深入理解Java的整型类型:如何实现2+2=5?
- Tecplot 360 按教程安装完毕后,弹出“Is your Tecplot 360 EX liense valid?”【终极解决办法】
- 的it生活_在日本生活了10年的IT女,聊聊回国工作的亲身经历
- as it exceeds the max of 500KB._IT狂人第一季 | 如何考察员工
- android 禁用dlsym_Android 7.0 dlopen 函数分析
- java 输入流关闭顺序_JAVA的节点流和处理流以及流的关闭顺序
- print writer保留原有信息写文件_Python读写EXCEL文件常用方法大全 - pythonputao
- Android无需权限保存文件,即使使用用户权限,也无法在外部存储上保存文件[Android]...