一、前言

这道题目的时间复杂度卡的很死,需要在算法设计和细节上仔仔细细的考虑才能通过。非常考验对最短路算法的基础理解和灵活运用,是一道值得细细品味的图论题。

二、题面分析

题目链接:Acwing:新年好

重庆城里有 n 个车站,m 条 双向 公路连接其中的某些车站。每两个车站最多用一条公路连接,从任何一个车站出发都可以经过一条或者多条公路到达其他车站,但不同的路径需要花费的时间可能不同。在一条路径上花费的时间等于路径上所有公路需要的时间之和。佳佳的家在车站 1,他有五个亲戚,分别住在车站 a,b,c,d,e。过年了,他需要从自己的家出发,拜访每个亲戚(顺序任意),给他们送去节日的祝福。怎样走,才需要最少的时间?输入格式
第一行:包含两个整数 n,m,分别表示车站数目和公路数目。第二行:包含五个整数 a,b,c,d,e,分别表示五个亲戚所在车站编号。以下 m 行,每行三个整数 x,y,t,表示公路连接的两个车站编号和时间。输出格式
输出仅一行,包含一个整数 T,表示最少的总时间。数据范围
1≤n≤50000,
1≤m≤1e5,
1<a,b,c,d,e≤n,
1≤x,y≤n,
1≤t≤100
输入样例:
6 6
2 3 4 5 6
1 2 8
2 3 3
3 4 4
4 5 5
5 6 2
1 6 7
输出样例:
21

分析:第一眼反应以为是Floyd解题,然后看到数据范围直接傻了。然后想到先枚举所有可能的路线再依次求最短路,然后马上想到时间复杂度也不允许。在仔细想想后,我们找到一个突破口----亲戚一共只有5个,只要我们能先预处理好5个亲戚和自己的最短距离,然后再进行DFS遍历,时间复杂度就可以刚刚好达到我们的目的。但是即使思路是对的,在代码实现上也要万分小心。有很多细节都是要注意到。

三、代码详解

//#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 7;int n, m;
int p[6];  //简单的离散化处理
int h[N], e[N], ne[N], w[N], id = 1;
int dist[6][N];  //dist[i][j]:编号为i的点到点j的距离
bool ch[N];  //dijkstra查重
bool st[6];  //dfs查重void add(int a, int b, int c)
{ne[id] = h[a];h[a] = id;e[id] = b;w[id] = c;id++;
}
int dfs(int step, int now, int res)  //步数、当前点的编号、已经走的距离
{if (step == 6)  //到6就说明走完5步了{return res;  //返回答案}int ans = INF;  //定义一个足够大的初始答案for (int i = 1; i <= 5; i++)  //枚举每一个亲戚{if (!st[i])  //如果这个点没走过{st[i] = true;ans = min(ans, dfs(step + 1, i, res + dist[now][p[i]]));   //找最小值st[i] = false;   //时光回溯}}return ans;   //返回最后的答案
}
void dijkstra(int s, int dist[ ])  //放进起点和到起点距离的数组,由于这里数组放进去的是地址,所以会直接修改全局变量
{mem(ch, 0);mem(dist, INF);priority_queue<PII, vector<PII>, greater<PII>> q;   //小根堆,不要写成了大根堆dist[s] = 0;  //起点距离为0q.push({ 0, s });  //放进优先队列while (q.size()){auto te = q.top();q.pop();int d = te.first;int idx = te.second;if (ch[idx] == 1)  //同一个点不被用来更新两次continue;ch[idx] = 1;for (int i = h[idx]; ~i; i = ne[i]){int j = e[i];if (dist[j] > d + w[i]){dist[j] = d + w[i];q.push({ dist[j], j });}}}}void solve()
{mem(dist, INF);mem(h, -1);cin >> n >> m;for (int i = 1; i <= 5; i++)cin >> p[i];while (m--){int a, b, c;cin >> a >> b >> c;add(a, b, c);add(b, a, c);}p[0] = 1;for (int i = 0; i <= 5; i++)  //5次dijkstra更新,多了一点都会tle掉dijkstra(p[i], dist[i]);cout << dfs(1, 0, 0);//DFS跑......
}int main()
{std::ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);solve();return 0;
}

【图论】新年好(最短路的综合问题)相关推荐

  1. 算法提高课-图论-单源最短路的综合应用-AcWing 1135. 新年好:dijkstra和dfs暴搜结合

    题目分析 来源:acwing 分析: 先预处理出从1,a,b,c,d,e出发到其他所有点的单源最短路.存在二维数组dist[6][N]中 dfs暴搜所有拜访顺序,共有5!种,对于每一种拜访顺序,可以通 ...

  2. [AcWing算法提高课]之图论 单源最短路的综合应用(C++题解)

    目录 1)热浪(板子题) (朴素dijkstra) O(n2) (堆优化dijkstra) O((n+m)logm) (spfa) O(m) 2)信使 3)香甜的黄油 4)最小花费 5) 最优乘车 6 ...

  3. 算法提高课-图论-单源最短路的综合应用-AcWing 342. 道路与航线:最短路dijkstra、拓扑排序 、综合题、好题

    题目分析 来源:acwing 分析: 道路:双向,边权非负, 航线:单向,边权可正可负,且无环. 根据题意,点可以分为很多团(连通块),团内部只有道路(道路是双向的,而且是连通的,所以不能存在航线,否 ...

  4. 【图论专题】单源最短路的综合应用

    单源最短路径经常与DFS.DP.二分.拓扑排序等算法的结合使用. 题目列表: 题目 算法 AcWing 1135. 新年好 最短路+DFS AcWing 340. 通信线路 二分+双端队列BFS Ac ...

  5. 【图论算法】 最短路,次短路,k短路总结

    在图论里,最短路,次短路,k短路的问题很常见. 这里总结一下. 存图技巧 数据小,稠密图的一般用邻接矩阵 稀疏图,数据大一般用邻接表(vector,链式前向星都可) 邻接矩阵 const int ma ...

  6. POJ 3268 迪杰斯特拉图论 置换找最短路

    题目:https://vjudge.net/problem/POJ-3268 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numb ...

  7. 单/全源最短路的综合应用(未完待续...)

    目录 一.单源最短路 1.1 AcWing 1129. 热浪 1.2 AcWing 1128. 信使 1.3 AcWing 1127. 香甜的黄油 1.4 AcWing 1126. 最小花费 1.5 ...

  8. 算法提高课-图论-单源最短路的建图方式-AcWing 920. 最优乘车:bfs求最短路、建图

    题目分析 来源:acwing 分析: 本题难在抽象建图上,这里采用的建图方式是:同一条公交线路上,前面的站点都可以连一条有向边到其后面的站点,且边权都为1. 由于边权都是1,可以用bfs来求最短路. ...

  9. 算法提高课-图论-单源最短路的建图方式-AcWing 1127. 香甜的黄油:spfa最短路

    题目分析 来源:acwing 分析: 多源汇最短路.所以我们首先想到的是floyd算法, 可是它的复杂度是O(n3)O(n^3)O(n3),会超时.所以我们需要另外考虑. 任意一个点作为起点求出到所有 ...

  10. 算法提高课-图论-单源最短路的建图方式-AcWing 1128. 信使:dijkstra、 最短路取最大值

    题目分析 来源:acwing 分析:广播模型,求整个网络所有点都被广播到,需要多少时间. 本题核心:对于每个点来说,它接收到信的时间,是等于它到指挥部的最短距离. 所以,所有点被广播到,就是求指挥部到 ...

最新文章

  1. 你必须会的DFS的递归实现与堆栈实现
  2. roast和roasting区别_《吐槽大会》的英文居然是roast!为什么?
  3. python七夕快乐图片_提前祝七夕快乐图片
  4. 大数据之Kafka集群安装及简单使用
  5. python的交互式解释器_python3.4.1解释器python交互式图形编程实例(三)
  6. python同或符号_奇技淫巧,还是正统功夫? - Python推导式最全用法
  7. 如何上传文件及文件夹到IPFS
  8. Qt中焦点策略FocusPolicy的使用
  9. mysql利用树建立索引_MYSQL(一)——-为什么使用B+树或者B-树做为索引结构? – 算法网...
  10. 在Linux下禁用IPv6的方法小结
  11. CSS 样式里面的逗号和空格之间的区别
  12. 事半功倍,在JCreator中查询java API
  13. 仿qq局域网聊天软件 c++ 非mfc 数据库
  14. ps中基色 混合色 结果色是什么
  15. ie禁用java怎么办,您如何解决IE中禁用javascript的问题?
  16. 教你制作第一个C++游戏!#1 引入
  17. Docker从0到1
  18. 使用 WPF+ ASP.NET MVC 开发 在线客服系统 (一)
  19. dataX和dataX-Web使用总结
  20. Android内、外存储 易混淆点剖析(/mnt/sdcard、/storage/sdcard0、/storage/emulated/0等区别)

热门文章

  1. 【OCP-052】052认证考试新题库整理-第9题
  2. [数据结构]链表的实现在PHP中
  3. C语言编程入门——程序练习(下)
  4. eclipse debug 的断点查看和清除
  5. Win7-64位 Cygwin编译Redis
  6. 原声socket 向服务端发长连接
  7. 理解委托的两类必要方法
  8. [Misc]IE浏览器真正全屏幕操作技巧
  9. redis 主从原理
  10. 短视频仿抖音源码--探索短视频+时代