Dijkstra

PAT (Advanced Level) Practice Dijkstra 相关题

目录

  • 《算法笔记》重点摘要
  • 1003 Emergency (25)

《算法笔记》 10.4.1 Dijkstra 重点摘要

对任意给出的图 G(V,E) 和 起点 S,终点 T,求 S 到 T 的最短路径

1. 简介

  • 解决单源最短路问题
  • 只能处理所有边权均非负的情况

    若出现负数,最好使用 SPFA 算法

2. 邻接矩阵

const int MAXV = 1000;
const int INF = 0x3fffffff;
int n, G[MAXV][MAXV], d[MAXV], pre[MAXV];
bool vis[MAXV] = {false};
void Dijkstra(int s){
fill(d, d + MAXV, INF);
d[s] = 0;
for (int i = 0; i < n; i++) pre[i] = i;
for (int i = 0; i < n; i++){
int u = -1, MIN = INF;
for (int j = 0; j < n; j++){ // 找未访问结点中 d[] 最小的
if (!vis[j] && d[j] < MIN){
u = j;
MIN = d[j];
}
}
if (u == -1) return; // 找不到 d[u] < INF 点,说明剩下的点与起点 s 不连通
vis[u] = true;
for (int v = 0; v < n; v++){
if (!vis[v] && G[u][v] != INF && d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];
pre[v] = u;
}
}
}
}
void DFS(int s, intv){
if (v == s){
printf("%d", s);
return;
}
DFS(s,pre[v]);
printf(" %d", v);
}

3. 第二标尺

第一标尺为距离

(1) 新增边权

如边的花费

int cost[MAXV][MAXV], c[MAXV];
fill(c, c + MAXV, INF);
c[s] = 0;
for (int v = 0; v < n; v++){
if (!vis[v] && G[u][v] != INF){
if (d[u] + G[u][v] == d[v] && c[u] + cost[u][v] < c[v]){
pre[v] = u;
c[v] = c[u] + cost[u][v];
}
else if (d[u] + G[u][v] < d[v]){
pre[v] = u;
d[v] = d[u] + G[u][v];
c[v] = c[u] + cost[u][v];
}
}
}
(2) 新增点权

如点的权重

int weight[MAXV], w[MAXV] = {0};
w[s] = weight[s];
for (int v = 0; v < n; v++){
if (!vis[v] && G[u][v] != INF){
if (d[u] + G[u][v] == d[v] && w[u] + weight[v] > w[v]){
pre[v] = u;
w[v] = w[u] + weight[v];
}
else if (d[u] + G[u][v] < d[v]){
pre[v] = u;
d[v] = d[u] + G[u][v];
w[v] = w[u] + weight[v];
}
}
}
(3) 求最短路径条数
int num[MAXV] = {0};
num[s] = 1;
for (int v = 0; v < n; v++){
if (!vis[v] && G[u][v] != INF){
if (d[u] + G[u][v] == d[v]{
pre[v] = u;
num[v] += num[u];
}
else if (d[u] + G[u][v] < d[v]){
pre[v] = u;
d[v] = d[u] + G[u][v];
num[v] = num[u];
}
}
}

1003 Emergency (25)

题目思路

  • 两个标尺:距离,点权;且要求最短路径数
#include<iostream>
using namespace std;
const int MAXN = 500, INF = 0x3fffffff;
int n, s, t, G[MAXN][MAXN], weight[MAXN], d[MAXN], pathnum[MAXN], w[MAXN] = {0};
bool vis[MAXN] = {false};
void Dijkstra(){
fill(d, d + MAXN, INF);
d[s] = 0;
pathnum[s] = 1;
w[s] = weight[s];
for (int i = 0; i < n; i++){
int u = -1, MIN = INF;
for (int j = 0; j < n; j++){
if (!vis[j] && d[j] < MIN){
u = j;
MIN = d[j];
}
}
vis[u] = true;
for (int v = 0; v < n; v++){
if (!vis[v] && G[u][v] != INF){
if (d[v] == d[u] + G[u][v]){
pathnum[v] += pathnum[u];
if (w[v] < w[u] + weight[v]) w[v] = w[u] + weight[v];
}
else if (d[v] > d[u] + G[u][v]){
d[v] = d[u] + G[u][v];
w[v] = w[u] + weight[v];
pathnum[v] = pathnum[u];
}
}
}
}
}
int main()
{
int m, u, v, len;
scanf("%d%d%d%d", &n, &m, &s, &t);
for (int i = 0; i < n; i++) scanf("%d", &weight[i]);
fill(G[0], G[0] + MAXN * MAXN, INF);
for (int i = 0; i < m; i++){
scanf("%d%d%d", &u, &v, &len);
G[u][v] = len;
G[v][u] = len;
}
Dijkstra();
printf("%d %d", pathnum[t], w[t]);
return 0;
}
  • fill(G[0], G[0] + MAXN * MAXN, INF) 注意二维数组要取首地址作为指针类型不能直接用数组名,因为它相当于是一维数组的指针,而参数要求是指针

PAT甲级 Dijkstra 相关题_C++题解的更多相关文章

  1. PAT甲级 二叉树 相关题_C++题解

    二叉树 PAT (Advanced Level) Practice 二叉树 相关题 目录 <算法笔记> 重点摘要 1020 Tree Traversals (25) 1086 Tree T ...

  2. PAT甲级 二叉查找树 相关题_C++题解

    二叉查找树 PAT (Advanced Level) Practice 二叉查找树 相关题 目录 <算法笔记> 重点摘要 1099 Build A Binary Search Tree ( ...

  3. PAT甲级 图 相关题_C++题解

    图 PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目 目录 1122 Hamiltonian Cycle (25) 1126 Eulerian P ...

  4. PAT甲级 树 相关题_C++题解

    树 目录 <算法笔记>重点摘要 1004 Counting Leaves (30) 1053 Path of Equal Weight (30) 1079 Total Sales of S ...

  5. PAT甲级 堆 相关题_C++题解

    堆 目录 <算法笔记>重点摘要 1147 Heaps (30) 1155 Heap Paths (30) <算法笔记> 9.7 堆 重点摘要 1. 定义 堆是完全二叉树,树中每 ...

  6. PAT甲级 散列题_C++题解

    散列 PAT (Advanced Level) Practice 散列题 目录 <算法笔记> 重点摘要 1002 A+B for Polynomials (25) 1009 Product ...

  7. PAT甲级 字符串处理题_C++题解

    字符串处理题 目录 <算法笔记> 重点摘要 1001 A+B Format (20) 1005 Spell It Right (20) 1108 Finding Average (20) ...

  8. PAT甲级 并查集 相关题_C++题解

    并查集 PAT (Advanced Level) Practice 并查集 相关题 <算法笔记> 重点摘要 1034 Head of a Gang (30) 1107 Social Clu ...

  9. PAT甲级 图的遍历 相关题_C++题解

    图的遍历 PAT (Advanced Level) Practice 图的遍历 相关题 目录 <算法笔记>重点摘要 1021 Deepest Root (25) 1076 Forwards ...

随机推荐

  1. FLUENT质量加权平均和面积加权平均的区别【转载】

    转载自:http://blog.sina.com.cn/s/blog_7ef78d170101bhfn.html 网上关于fluent中质量加强平均(Mass-Weighted Average)和面积 ...

  2. Coupled和segregated【转载】

    转载自:http://blog.sina.com.cn/s/blog_67873f6c0100ltq6.html 问题1: 我看中文帮组里说是'分离'的意思?我绝对翻译不太好,请问有更好的翻译吗? 和 ...

  3. [Linux] 内核通知链 notifier

    Linux 内核中每个模块之间都是独立的,如果模块需要感知其他模块的事件,就需要用到内核通知链. 最典型的通知链应用就是 LCD 和 TP 之间,TP 需要根据 LCD 的亮灭来控制是否打开关闭触摸功 ...

  4. 树莓派 pip 手动安装 和使用阿里云源

    在 /etc/pip.conf 添加如下内容,启用源 [global] extra-index-url=https://www.piwheels.org/simple 下载后 pip install ...

  5. 女士品茶 | The Lady Tasting Tea | 统计学史

    The Lady Tasting Tea - How Statistics Revolutionized Science in the Twentieth Century 本书只讨论了20世纪这100 ...

  6. FCKeditor编辑器第一次点击总是报错(上传图片) 之后就好了

    错误:   Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index. FCKeditor编辑器第一次点击总是报错(上 ...

  7. 【JDBC】使用properties连Oracle数据库,使用DatabaseMetaData获取字段的注释

    简单的打铁代码如下: package com.hy.propertyConn; import java.sql.Connection; import java.sql.DatabaseMetaData ...

  8. 阿里云ECS服务器环境搭建(1) —— ubuntu 16.04 图形界面的安装

    阿里云ECS服务器环境搭建(1) —— ubuntu 16.04 图形界面的安装1. 背景在我们购买阿里云ECS服务器之后,默认的系统环境是很干净的,我购买的是ubuntu16.04,远程登录进入之后 ...

  9. docker在windows下上传文件到容器

    我的系统是windows10,docker是用DockerToolbox工具安装的,安装完之后会默认挂载Windows的C:/Users目录,在docker里面对应路径是/c/Users,docker ...

  10. word: 插入或修改文字时后面的字消失 解决办法

    在编辑Word文档中的文字时,我们有时需要插入或修改文字,可是在插入或修改时会发现改动处后面的文字会消失.比如插入或修改3个字,后面的文字随之也会消失3个,这时该怎么办呢? 点击-“文件”-“选项”- ...