UVA_1599 Ideal Path
2021/12/30 6:07:07
本文主要是介绍UVA_1599 Ideal Path,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题意
给一个n个点m条边(2≤n≤100000,1≤m≤200000)的无向图,每条边上都涂有一种颜色。求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小。一对结点间可能有多条边,一条边可能连接两个相同结点。输入保证结点1可以达到结点n。颜色为1~109的整数。
探索
理解题目
- 所求是什么?
所求是两点之间最短路径中的一个 - 提供的数据是什么?
n个结点和m条边
寻找关系,拟定方案
- 这道题我们应该用什么数据结构来完成?
图 - 关于这道题,你有什么相关的图的基本模型你觉得可以使用?
BFS,因为要求最短路径,是BFS,DFS对最短路径没有任何帮助 - BFS有什么作用,在这个题目中可以利用
BFS可以算出从一个结点出发到其他结点的最短距离 - 为了充分应用这个算法,很明显,通过BFS算法我们可以得到长度的大小,但是还是没有办法得到路径,你有遇见过任何长度到具体对象的算法吗?
。。。好像没有 - 那如果我们没有现成的想法的时候,我们或许得先判断,是否我们能得到的条件满足目标?
嗯,距离和选择的结点的关系应该是相互制约的,结点定了距离也就定了,而距离定了,我们得到的也就是能满足最短路径的所有路径了 - 既然我们知道了是可以满足等价推导的条件的,你认为这个条件是什么?我是说为什么距离就决定了路径,用将路径单纯用距离表示
我不知道。。但是肯定是距离会影响结点,结点也会影响长度 - 很多时候当我们知道明摆着会有影响,但是我们去没有办法表示的时候,或许就是因为递归的思想,就像我们一开始写代码的时候,一时之间总觉得recursions难以理解,在现实生活中也会有这样的时候,现在我想你的感受或许和做recursion是一开始的感觉是一样的,就像我们对待recursion的策略一样,把规模降低降低,让我们从n变到足够低,画图永远是最直观的东西!话一个一目了然的情况,然后从画中标出我们想要得到,和我们已知的,在这里是我们的已知是每个结点的最短距离,我们想要的是路径
感觉不太对,我不选4是因为1-5就是2而1-4=2说明肯定不经过4可以排除,但是要是说我选2和3因为是和1的距离是1<2也觉得还不对,要是2和3根本不到5呢? - 嗯,可见选这个结点条件是要能够到5并且其距离要每一次都是到5的距离减一,那么问题就变成了连通性的问题,我们可以使用dfs每个结点判断是否能到5,在进行判断,我想我们是会做的,但是是否,有点太过于复杂
嗯,是的,每个结点都要判断,就。。。 - 很多时候,一个事物从不同的角度看有不同的视角,或许从开头复杂,从结尾就简单了,多探索,多思考
哦我明白了,从5出发,我反正所有的有距离的都是可以到5的,这样我们就可以知道,对每一个结点,它能走的下一个结点有那些,进行组合就可以得到所有的路线(这个要得到所有的路径是可以的,但是有很多的for循环!而且还不知道怎么记录)
- 当然下一个条件是让我们找出the colors of passages inthe order they must be passed in the ideal path.首先回顾一下第3章中介绍的“字典序”。对于字符串来说,字典序就是在字典里的顺序。例如,ab在cd的前面,cde在a的后面,abcd在abcde的前面。这个定义可以扩展到序列:序列(1, 2)在(3, 4, 5)的前面,(4, 5, 6)在(4, 5)的后面。所有我们要找到在所有段中可走的线路中最短的一个!---其实这个让这个题目变简单了。。。
tip:
一对结点间可能有多条边,一条边可能连接两个相同结点
一开始处理,不要环,选取两个结点之间最近的点
经验
解题方法:
- 数据结构确定
- 选择算法
- 当我们选择了相似的算法之后,却依旧觉得很遥远的时候,我们要使用等价判断,看看我们已知的数据是否是等价的,是否可以推出来
- 当我们明析了数据是可以实现等价的时候,去常常觉得难以描述,我们要思考是否是因为recursion,而对付recursion最好的方法就是规模减少+画图
- 注意:画图永远要有最简单的图示表达 当我们想要使用画图使用未知表达已知,我们就要在图中画出已知,然后画出我们要得到的,然后去观察思考
- 当我们解题的时候,已经有了差不多的解法,却觉得不过大气简洁的时候,或许我们需要换一个视角,就像看的《今日说法-烟锁殡仪馆》从受害者入手感到困难,我们就推导杀害人,或许会看见不一样的东西,从头或从尾
图: - 图_双向bfs 双向bfs+字典序
- 图_存储_邻接矩阵 图的边的存储,太大,不能用数组
代码: - 循环_明析自己到底要什么不要无脑的就是index 想要的是结点,但是之间顺手地就写i,j...
// 错误 for (int i = 0; i < next.size(); i++) { for (int j = 0; j < edge[i].size(); j++) { // 正确 for (int i = 0; i < next.size(); i++) { int thisedge = next[i]; for (int j = 0; j < edge[thisedge].size(); j++) {
代码
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <vector> #include <queue> #include <string.h> //#define LOCAL using namespace std; const int maxn = 100000+5; const int INF = 1e9; struct Edge { int u; int v; int c; Edge(int a,int b,int d):u(a),v(b),c(d){} }; vector<Edge> edge[maxn]; int d[maxn]; int used[maxn]; int n, m; void rebfs() { memset(d, -1, sizeof(d)); memset(used, 0, sizeof(used)); queue<int> que; que.push(n); used[n] = 1; d[n] = 0; while (que.size()) { int nownode = que.front(); que.pop(); for (int i = 0; i < edge[nownode].size(); i++) { int nexnode = edge[nownode][i].v; if (!used[nexnode]) { d[nexnode] = d[nownode] + 1; used[nexnode] = 1; que.push(nexnode); } } } } vector<int> answer; void bfs() { memset(used, 0, sizeof(used)); answer.clear(); vector<int> next; used[1] = 1; next.push_back(1); int path = d[1]; while (path--) { int min = INF; for (int i = 0; i < next.size(); i++) { int thisedge = next[i]; for (int j = 0; j < edge[thisedge].size(); j++) { int theedge = edge[thisedge][j].v; if (d[theedge] == d[thisedge] - 1 && edge[thisedge][j].c < min) min = edge[thisedge][j].c; } } answer.push_back(min); vector<int> next2; for (int i = 0; i < next.size(); i++) { int thisedge = next[i]; for (int j = 0; j < edge[thisedge].size(); j++) { int theedge = edge[thisedge][j].v; if (d[theedge] == d[thisedge] - 1 && edge[thisedge][j].c == min && !used[theedge]) { next2.push_back(theedge); used[theedge] = 1; } } } next = next2; } } int main() { #ifdef LOCAL freopen("output.txt", "w", stdout); #endif // LOCAL while (scanf("%d%d", &n, &m) == 2) { for (int i = 0; i <= n; i++) { edge[i].clear(); } int a = m; while (a--) { int u, v, c; cin >> u >> v >> c; if (u != v) { Edge e = Edge(u, v, c); edge[u].push_back(e); e = Edge(v, u, c); edge[v].push_back(e); } } rebfs(); bfs(); printf("%d\n", d[1]); for (int i = 0; i < answer.size(); i++) { if (i == 0) printf("%d", answer[i]); else printf(" %d", answer[i]); } printf("\n"); } return 0; }
这篇关于UVA_1599 Ideal Path的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?