题目分析



来源:acwing
分析:
本题有多组测试数据,如果对每个源点暴力使用dijkstra,会超时。

好的做法:建立虚拟源点S,让S到所有真实起点的边权为0,这样原问题就可以转换为从虚拟源点S到终点的单元最短路问题。

建立虚拟源点的写法:会TLE,对了5个点

尝试对每个起点进行dijkstra,也会TLE,结果对了7个点!!天哪。

第三次尝试:写了反向dijkstra,即从终点为起点,反向建边,结果还是TLE,对了9个点,就有点生气!

代码1(对了5个点)

#include<bits/stdc++.h>
using namespace std;
const int N = 1010, INF = 0x3f3f3f3f;
const int M = 20010;
typedef pair<int,int> PII;
#define x first
#define y second
int n, m, s;
int h[N],e[M],w[M],ne[M],idx;
int dist[N];
bool st[N];void add(int a, int b, int c){e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}int dijkstra(){memset(dist, 0x3f, sizeof dist);memset(st, 0, sizeof st);dist[0] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0,0});while(heap.size()){auto t = heap.top();heap.pop();int ver = t.y, distance = t.x; if(st[ver]) continue;st[ver]  = true;for(int i = h[ver]; ~i; i = ne[i]){int j = e[i];if(dist[j] > distance + w[i]){dist[j] = distance + w[i];heap.push({dist[j], j});}}}if(dist[s] == INF) return -1;return dist[s];
}int main(){while(scanf("%d%d%d",&n, &m, &s) != -1){memset(h, -1, sizeof h);int p, q, t;while(m --){scanf("%d%d%d", &p, &q, &t);add(p, q, t);}int w;scanf("%d",&w);for(int i = 0; i< w; i++){int ver;scanf("%d",&ver);add(0,ver, 0);}printf("%d\n", dijkstra());}
}

代码2(对了9个点)

#include<bits/stdc++.h>
using namespace std;
const int N = 1010, INF = 0x3f3f3f3f;
const int M = 20010;
typedef pair<int,int> PII;
#define x first
#define y second
int n, m, s;
int h[N],e[M],w[M],ne[M],idx;
int dist[N];
bool st[N];
int path[N];void add(int a, int b, int c){e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}void dijkstra(){memset(dist, 0x3f, sizeof dist);memset(st, 0, sizeof st);priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0,s});dist[s] = 0;while(heap.size()){auto t = heap.top();heap.pop();int ver = t.y, distance = t.x; if(st[ver]) continue;st[ver]  = true;for(int i = h[ver]; ~i; i = ne[i]){int j = e[i];if(dist[j] > distance + w[i]){dist[j] = distance + w[i];heap.push({dist[j], j});}}}
}int main(){while(scanf("%d%d%d",&n, &m, &s) != -1){memset(h, -1, sizeof h);int p, q, t;while(m --){scanf("%d%d%d", &p, &q, &t);add(q, p, t);}dijkstra();int w, res = INF;scanf("%d",&w);int ver;while(w --){cin >> ver;res = min(res, dist[ver]);}if(res == INF) res = -1;printf("%d\n", res);}
}

代码3(ac:也是虚拟源点的写法,结果就ac了,真是奇了怪了!!!)

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;typedef pair<int, int> PII;
//建立虚拟源点0
const int N = 1010, M = 40010, INF = 0x3f3f3f3f;
int n, m, s;
int h[N], e[M], w[M], ne[M], idx;
int dist[N];
bool st[N];void add(int a, int b, int c) {e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
int dijkstra() {memset(dist, 0x3f, sizeof dist);memset(st, 0, sizeof st);priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 0});dist[0] = 0;while (heap.size()) {PII t = heap.top();heap.pop();int ver = t.y, distance = t.x;if (st[ver]) continue;st[ver] = true;for (int i = h[ver]; ~i; i = ne[i]) {int j = e[i];if (dist[j] > distance + w[i]) {dist[j] = distance + w[i];heap.push({dist[j], j});}}}if (dist[s] == INF) return -1;return dist[s];
}
int main() {while (scanf("%d%d%d", &n, &m, &s)!= -1) {memset(h, -1, sizeof h);idx = 0;int x;while (m--) {int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c);}scanf("%d", &x);while (x--) {int stop;scanf("%d", &stop);add(0, stop, 0);}cout << dijkstra() << endl;}return 0;
}

题目来源

https://www.acwing.com/problem/content/description/1139/

算法提高课-图论-单源最短路的扩展应用-AcWing 1137. 选择最佳线路:多源最短路、虚拟源点相关推荐

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

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

  2. 算法提高课-图论-单源最短路的建图方式-AcWing 903. 昂贵的聘礼:建图巧妙、dijkstra、考虑等级

    题目分析 来源:acwing 由于终点是1号节点,建立虚拟节点S,如下建图(根据样例画图).S出发和每个点直连的边权代表直接买该物品花的金币数:而由S到1的任意一条通路,边权之和就是花费的金币数.所以 ...

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

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

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

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

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

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

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

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

  7. 算法提高课-图论-单源最短路的建图方式-AcWing 1126. 最小花费:dijkstra求最长路

    题目分析 来源:acwing 分析: 链条转移:start * (1-w1) * (1- w2) * (1- w3) -(1-wn) = 100,要start最小,则w =(1-w1) * (1- w ...

  8. 算法提高课-图论-单源最短路的建图方式-AcWing 1129. 热浪:dijkstra裸题

    题目分析 来源:acwing 分析: ac代码 朴素的dijkstra() ,时间复杂度O(n2)O(n^2)O(n2) #include<bits/stdc++.h> using nam ...

  9. 算法提高课-图论-有向图的强连通分量-AcWing 367. 学校网络:强连通分量、tarjan算法

    文章目录 题目解答 题目来源 题目解答 来源:acwing 分析: 第一问:通过tarjan算法求出强连通分量并且缩点后,统计入度为0的点的个数p即可. 第二问,至少加几条边才能使图变成强连通分量?这 ...

最新文章

  1. (翻译)Quartz官方教程——第七课:TriggerListeners 和 JobListeners
  2. python3.8 新特性
  3. Winform中使用用户控件实现带行数和标尺的RichTextBox(附代码下载)
  4. centos 6.5安装mysql5.7,centos6.5安装mysql5.7
  5. MySQL多表事务课堂笔记
  6. 函数传参string_JavaScript 高阶函数入门浅析
  7. python3获取用户输入_python3.4控制用户输入与输出
  8. golang for循环_10. Go语言流程控制:for 循环
  9. 3位数反序数c语言,C语言求助!一个三位数的逆序数,总是编不对
  10. sunplus 8202v iop源代码阅读笔记——2
  11. android studio gradle 打jar 包 (混淆+第三方库包)
  12. Centos 6.5之LAMP学习笔记
  13. XTT钠盐 XTT sodium salt/Resorufin (high purity) 还原酶底物
  14. 谁说门户已死?从世界杯看新浪的四大优势
  15. php实现迅雷链接的加密解密
  16. 周报|吉吉拍APP正式上架应用宝
  17. 酷派s6、Coolpad 9190l_C00 无log信息输出解决方法
  18. 【历史上的今天】7 月 25 日:IBM 获得了第一项专利;Verizon 收购雅虎;亚马逊发布 Fire Phone
  19. 202203读书-《 测试有道:微软测试技术心得》
  20. 五金机电行业智能供应链管理系统解决方案:数智化供应链为传统产业“造新血”

热门文章

  1. 面向对象数据库和关系数据库的区别
  2. bzoj1072: [SCOI2007]排列perm
  3. 数据结构--百度百科
  4. Xcode环境变量,Build Settings参数
  5. ASP.NET中使用Global.asax文件
  6. 14.parfor并行循环处理
  7. Keil 运行.bat脚本文件
  8. CentOS7+CDH5.14.0安装全流程记录,图文详解全程实测-1虚拟机安装及环境初始化
  9. SVM学习笔记1-问题定义
  10. 管理和安装 chart - 每天5分钟玩转 Docker 容器技术(168)