#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <iostream>
using namespace std; const int MAXV = ;
const int INF = ; struct Node
{
int v,dis;
}; vector<Node> Adj[MAXV]; int n;//n为顶点数,图G使用邻接表实现,MAXV为最大顶点数(点数决定如何遍历边)
int m;// 边数(决定输入什么样的图)
int s;//起点 int d[MAXV];//起点到达各个点的最短路径长度
bool vis[MAXV] = {false};//标记数组,vis[i]==true表示已访问,初值均为false int pre[MAXV]={}; //记录到某一个点的前驱 void Dijkstra(int s)
{
fill(d,d+MAXV,INF);
d[s] = ;//起点s到达自身的距离为0 //遍历所有的点
for(int i=;i<n;i++)
{
//u为使得d[u]最小的点,MIN存放该最小的d[u]
int u = -,MIN = INF;
//每一趟找一个已连通的最短路径的点出来
for(int j=;j<n;j++)
{ if(vis[j] == false && d[j] < MIN)
{
u = j;
MIN = d[j];
}
} //找不到小于INF的d[u],说明剩下的顶点和起点s不连通
if(u == -)
{
return;
}
//找到了
else
{
vis[u] = true;//找到则标记成已访问,每一趟可以确定一个最短点 //遍历u能到达的所有顶点v,并判断以u为中转到j的距离是否比原来的小,如果小则更新
for(int j=;j < Adj[u].size();j++)
{ int v = Adj[u][j].v; //以当前最短路径的点为中转,看看是否比原来的距离小 ,如果小,则优化d[v]
if(vis[v] == false && d[u] + Adj[u][j].dis < d[v])
{
d[v] = d[u] + Adj[u][j].dis; //记录前驱
pre[v] = u;
}
}
}
}
} //输出从起点到v的最短路径
void print(int s,int v)
{
if(v == s)
{
cout << s << endl;
return;
} print(s,pre[v]);
cout<< v << endl;
} int main()
{
//顶点个数,边数,起点编号
cin >> n >> m >> s; int u,v,w;
Node tmp;
for (int i=;i<m;i++)
{
cin >> u >> v >> w;
tmp.v = v;
tmp.dis = w;
Adj[u].push_back(tmp);
} Dijkstra(s); for(int i=;i<n;i++)
{
cout << d[i] << " ";
} cout << endl;
print(,);
return ; }

练习: PAT A1003 Emergency

#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std; const int MAXV = ;
const int INF = ; //n为点数,m为边数,st和ed分别为起点和终点
//G为邻接矩阵,weight为点权
//d[]记录最短距离,w[]记录最大点权之和
int n,m,st,ed,G[MAXV][MAXV],weight[MAXV];
int d[MAXV],w[MAXV];
//vis[i] == true 表示顶点i已访问
bool vis[MAXV] = {false}; vector<int> pre[MAXV]; void Dijkstra(int s)
{
fill(d,d+MAXV,INF);
d[s] = ; //每次找出一个最短的点,一共找n个 ,最短的点就是在最短路径中的点,设置为访问
for(int i=;i<n;i++)
{
int u = -,MIN = INF;
//找最短的点
for(int j=;j<n;j++)
{
if(vis[j] == false && d[j] < MIN)
{
u = j;
MIN = d[j];
}
} if(u == - ) return;
vis[u] = true; //看u能到哪些点 ,并以u为中转,更新其他距离
//以u为中转,到v
for(int v=;v<n;v++)
{
if(vis[v] == false && G[u][v] != INF)
{
if(d[u] + G[u][v] < d[v])
{
d[v] = d[u] + G[u][v];
pre[v].clear();
//令v的前驱为u
pre[v].push_back(u);
}
else if(d[u]+G[u][v] == d[v])
{
pre[v].push_back(u);
}
}
}
}
} //求最大值
int optvalue = -INF;
//最优路径及临时路径
vector<int> path,tempPath;
//路径数+1
int totalCount = ; void DFS(int v)
{ // cout << endl;
//到达叶子节点,即起点
if(v == st)
{
totalCount++;
tempPath.push_back(v);
int value = ;
for(int i=;i<tempPath.size();i++)
{
// value = value + G[ tempPath[i] ][ tempPath[i+1] ];
value = value + weight[tempPath[i]];
} if(value > optvalue)
{
optvalue = value;
path = tempPath;
} //回溯
tempPath.pop_back();
return;
}
//将当期访问的点加入临时路径
tempPath.push_back(v);
//访问所有前驱
for(int i=;i<pre[v].size();i++)
{
//递归遍历所有前驱
DFS(pre[v][i]);
}
tempPath.pop_back();
} int main()
{
cin >> n >> m >> st >> ed;
for(int i=;i<n;i++)
{
cin >> weight[i];
} int u,v;
fill(G[],G[] + MAXV * MAXV,INF); for(int i=;i<m;i++)
{
cin >> u >> v;
cin >> G[u][v];
G[v][u] = G[u][v];
} Dijkstra(st); DFS(ed); cout << totalCount << " " << optvalue << endl;
return ;
}

PAT A1030 Travel Plan

#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
using namespace std; const int MAXV = ;
const int INF = ; //n为顶点数,m为边数,st和ed分别为起点和终点
//G为距离矩阵,cost为花费矩阵
//d[]用来记录最短距离,minCost记录最短路径上的最小花费
int n,m,st,ed,G[MAXV][MAXV],cost[MAXV][MAXV];
int d[MAXV],minCost = INF;
//是否被访问过
bool vis[MAXV] = {false};
//前驱
vector<int> pre[MAXV];
vector<int> tempPath,path;//临时路径与最优路径 void Dijkstra(int s)
{
fill(d,d+MAXV,INF);
d[s] = ;
//找出n个点
for(int i=;i<n;i++)
{
int u = -,MIN = INF;
//找最小路径且没有被访问的点
for(int j=;j<n;j++)
{
if(vis[j] == false && d[j] < MIN)
{
u = j;
MIN = d[j];
}
} //找不到则说明剩下的顶点和起点不连通
if(u == -)
{
return;
} vis[u] = true; //更新d[]
for(int v = ;v < n;v++)
{
//如果能到达则做为中转 ,看能否到达v,并判断以此为中转到v的距离是否比之前的d要小,如果小则更新
if(vis[v] == false && G[u][v] != INF)
{
if(d[u] + G[u][v] < d[v])
{
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if(d[u] + G[u][v] == d[v])
{
pre[v].push_back(u);
}
}
}
}
} //v为当前节点
void DFS(int v)
{
//到达叶节点
if(v == st)
{
tempPath.push_back(v);
int tempCost = ;//记录当前路径的花费之和
for(int i = tempPath.size() - ;i > ;i--)
{
int id = tempPath[i],idNext = tempPath[i-];
tempCost += cost[id][idNext];
} //如果小,则备份
if(tempCost < minCost)
{
minCost = tempCost;
path = tempPath;
} //回溯
tempPath.pop_back() ;
return;
} tempPath.push_back(v);
for(int i=;i<pre[v].size();i++)
{
DFS(pre[v][i]);
} tempPath.pop_back();
} int main()
{ cin >> n >> m >> st >> ed;
int u,v;
fill(G[],G[]+MAXV*MAXV,INF) ; for(int i=;i<m;i++)
{
cin >> u >> v;
cin >> G[u][v];
cin >> cost[u][v];
G[v][u] = G[u][v];
cost[v][u] = cost[u][v];
} Dijkstra(st); DFS(ed);//获取最优路径 for(int i=path.size() - ;i>=;i--)
{
cout << path[i] << " ";
}
cout << d[ed] << " " << minCost << endl;
return ;
}

图的最短路径Dijkstra的更多相关文章

  1. c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法

    c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法 图的最短路径的概念: 一位旅客要从城市A到城市B,他希望选择一条途中中转次数最少的路线.假设途中每一站都需要换车,则这个问题反映到图上就是 ...

  2. Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...

  3. 图的最短路径——dijkstra算法和Floyd算法

    dijkstra算法 求某一顶点到其它各个顶点的最短路径:已知某一顶点v0,求它顶点到其它顶点的最短路径,该算法按照最短路径递增的顺序产生一点到其余各顶点的所有最短路径. 对于图G={V,{E}};将 ...

  4. 图的最短路径-----------Dijkstra算法详解(TjuOj2870_The Kth City)

    做OJ需要用到搜索最短路径的题,于是整理了一下关于图的搜索算法: 图的搜索大致有三种比较常用的算法: 迪杰斯特拉算法(Dijkstra算法) 弗洛伊德算法(Floyd算法) SPFA算法 Dijkst ...

  5. 数据结构与算法-图的最短路径Dijkstra

    一  无向图单源最短路径,Dijkstra算法 计算源点a到图中其他节点的最短距离,是一种贪心算法.利用局部最优,求解全局最优解. 设立一个visited访问和dist距离数组,在初始化后每一次收集一 ...

  6. 带权图的最短路径算法(Dijkstra)实现

    一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...

  7. C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)

    1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...

  8. 图的最短路径---迪杰斯特拉(Dijkstra)算法浅析

    什么是最短路径 在网图和非网图中,最短路径的含义是不一样的.对于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径. 对于网图,最短路径就是指两顶点之间经过的边上权值之和最 ...

  9. 数据结构(C#):图的最短路径问题、(Dijkstra算法)

    今天曾洋老师教了有关于图的最短路径问题,现在对例子进行一个自己的理解和整理: 题目: 要求:变成计算出给出结点V1到结点V8的最短路径 答: 首先呢,我会先通过图先把从V1到V8的各种路径全部计算下来 ...

随机推荐

  1. ubuntu下Fiddler抓包

    参考 https://www.cnblogs.com/jcli/p/4474332.html https://www.jianshu.com/p/4505c732e378 1. 你要有个Mono环境, ...

  2. ArcEngine生成矩形缓冲区

    这里生成缓冲区肯定是根据点进行生成的,说是生成缓冲区其实是根据点生成面.具体思路如下:首先根据点获取要生成矩形缓冲区的四个顶点的坐标,然后将这四个点生成面即可得到所谓的矩形缓冲区. //首先获取要生成 ...

  3. tomcat8安装及配置

    首先是解压版的安装.很简单,直接解压到要安装的位置就OK了. 2.启动 bin目录下,执行startup.bat文件 3.浏览器中打开地址http://localhost:8080/

  4. 新建python的虚拟环境

    1.mkvirutalenv --python=E:\Users\00\AppData\Local\Programs\Python\Python37-32\python.exe article_spi ...

  5. 第二节:Series基本属性及方法(下)

  6. everyday two problems / 3.1

    T1.string 题意: 给定由小写字母组成的长度为 n 的字符串 将其所有 n * (n + 1) / 2 个子串按字典序排序 输出第 k 个子串 k > (n * (n + 1) / 2) ...

  7. Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method fail

    SpringBoot 单元测试报错 @RunWith(SpringRunner.class) @SpringBootTest public class ProductCategoryRepositor ...

  8. Leetcode 48.旋转矩阵

    旋转矩阵 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像. 示例 1: ...

  9. noip模拟赛 站军姿

    分析:纯数学题.相离和包含关系的可以很容易算出来答案,相交的话要先求出两个圆的面积,然后减掉中间重叠的部分,这一部分并不能直接求出来,但是可以求出两个扇形的面积,和它们围成的一个四边形的面积,加加减减 ...

  10. 网络流入门 Drainage Ditches

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) ...