#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXV=1000;
const int INF=100000000;
int n,m,s,G[MAXV][MAXV];
int d[MAXV];//起点到达各点的最短路径长度
bool vis[MAXV]={false};
void Dijkstra(int s){
fill(d,d+MAXV,INF);
d[s]=0;
for(int i=0;i<n;i++){
int u=-1,MIN=INF;
for(int j=0;j<n;j++){
if(vis[j]==false&&d[j]<MIN){
u=j;
MIN=d[j];
}
}
if(u==-1) return;
vis[u]=true;
for(int v=0;v<n;v++){
if(vis[v]==false&&G[u][v]!=INF&&d[u]+G[u][v]<d[v]){
d[v]=d[u]+G[u][v];
}
}
}
}
int main(){
int u,v,w;
cin>>n>>m>>s;
fill(G[0],G[0]+MAXV*MAXV,INF);
for(int i=0;i<m;i++){
cin>>u>>v>>w;
G[u][v]=w;
}
Dijkstra(s);
for(int i=0;i<n;i++){
cout<<d[i]<<" ";
}
return 0;
}

邻接表实现

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int INF=;
const int MAXV=;
int m,s,n,d[MAXV];//m个点n个边起点是s
bool vis[MAXV]={false};
struct Node{
int v,dis;
};
vector<Node>G[MAXV];
void dj(){
fill(d,d+MAXV,INF);
d[s]=;
for(int i=;i<m;i++){
int u=-,MAX=INF;
for(int j=;j<m;j++){
if(vis[j]==false&&d[j]<MAX){
u=j;
MAX=d[j];
}
}
if(u==-) return;
vis[u]=true;
for(int j=;j<G[u].size();j++){
int v=G[u][j].v;
if(vis[v]==false&&d[u]+G[u][j].dis<d[v]){
d[v]=d[u]+G[u][j].dis;//注意此处是G[u][j]而不是G[u][v]
}
}
}
}
int main(){
int uu,vv,w;
cin>>m>>n>>s;
for(int i=;i<n;i++){
cin>>uu>>vv>>w;
Node tp;
tp.dis=w;
tp.v=vv;
G[uu].push_back(tp);
}
dj();
for(int i=;i<m;i++){
cout<<d[i]<<" ";
}
return ;
}

测试:

6 8 0

0 1 1

0 3 4

0 4 4

1 3 2

2 5 1

3 2 2

3 4 3

4 5 3

代码解释:

 void d(){
//初始化图
//将出发点到出发点的距离设为0
for(循环n次){//n表示顶点数
//设当前欲访问的顶点下标为u=-1;
//设所有点中到起点距离最短的那个点的路径长为MAX=100000000000;
for(循环n次){
if(第n个点没有被访问&&该点到起点的路径最短){
MAX=最短路径;
u=n;//记录该点,即该点已经被访问
}
}
if(u==-1) return;//所有点已经被访问,函数结束
//标记u点被访问
for(n次循环){
if(该点没有被访问&&该点到新被访问顶点u的距离小于原来路径){
//更新路径
}
}
}
}

  视频解释:https://www.bilibili.com/video/av38254646/?redirectFrom=h5

时间复杂度=n*(n+n)

在实际解题中可能会出现多个权重的问题,直接的解题方法就是增加变量再重新划分逻辑,例如PAT A1003

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) – the number of cities (and the cities are numbered from 0 to N-1), M – the number of roads, C1 and C2 – the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.

Output

For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.
All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output

2 4

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXV=510;
const int INF=10000000;
bool vis[MAXV]={false};
int n,m,s,e,G[MAXV][MAXV],d[MAXV],num[MAXV],weight[MAXV],w[MAXV];
void dj(){
fill(d,d+MAXV,INF);
memset(num,0,sizeof(num));
memset(w,0,sizeof(w));
d[s]=0;
w[s]=weight[s];
num[s]=1;
for(int i=0;i<n;i++){
int MIN=INF,u=-1;
for(int j=0;j<n;j++){
if(vis[j]==false&&d[j]<MIN){
u=j;
MIN=d[j];
}
}
if(u==-1) return;
vis[u]=true;
for(int v=0;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];
w[v]=w[u]+weight[v];
num[v]=num[u];
}else if(d[u]+G[u][v]==d[v]){
if(w[u]+weight[v]>w[v]){
w[v]=weight[v]+w[u];
}
num[v]+=num[u];
}
}
}
}
}
int main(){ cin>>n>>m>>s>>e;
for(int i=0;i<n;i++){
cin>>weight[i];
}
int u,v,p;
fill(G[0],G[0]+MAXV*MAXV,INF);
for(int i=0;i<m;i++){
cin>>u>>v>>p;
G[v][u]=G[u][v]=p;
}
dj();
cout<<num[e]<<" "<<w[e];
return 0;
}

  还有PAT A1030

A traveler's map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format:

City1 City2 Distance Cost

where the numbers are all integers no more than 500, and are separated by a space.

Output Specification:

For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output.

Sample Input:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20

Sample Output:

0 2 3 3 40

增加变量的常规解法
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXV=510;
const int INF=100000000;
bool vis[MAXV]={false};
int n,m,s,e,G[MAXV][MAXV],d[MAXV],cost[MAXV],weight[MAXV][MAXV],pre[MAXV];
void dj(){
fill(d,d+MAXV,INF);
fill(cost,cost+MAXV,INF);
cost[s]=0;
d[s]=0;
for(int i=0;i<n;i++)
pre[i]=i;
for(int i=0;i<n;i++){
int MIN=INF,u=-1;
for(int j=0;j<n;j++){
if(vis[j]==false&&d[j]<MIN){
u=j;
MIN=d[j];
}
}
//if(u==-1) return;
vis[u]=true;
for(int v=0;v<n;v++){
if(vis[v]==false&&G[u][v]!=INF){
if(d[v]>d[u]+G[u][v]){
d[v]=d[u]+G[u][v];
cost[v]=cost[u]+weight[u][v];
pre[v]=u;
}else if(d[v]==d[u]+G[u][v]&&cost[u]+weight[u][v]<cost[v]){
cost[v]=cost[u]+weight[u][v];
pre[v]=u;
}
}
}
}
}
void f(int v){
if(v==s){
cout<<v<<" ";
return;
}
f(pre[v]);
cout<<v<<" ";
}
int main(){
cin>>n>>m>>s>>e;
int u,v,p,q;
fill(G[0],G[0]+MAXV*MAXV,INF);
for(int i=0;i<m;i++){
cin>>u>>v>>p>>q; weight[v][u]=weight[u][v]=q;
G[v][u]=G[u][v]=p;
}
dj();
f(e);
cout<<d[e]<<" "<<cost[e];
return 0;
}

  

模板式DFS+dj

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=100000000;
const int MAXV=510;
int d[MAXV],c[MAXV],G[MAXV][MAXV],cost[MAXV][MAXV];
bool vis[MAXV]={false};
int n,m,s,e,mincost=INF;
vector<int>pre[MAXV];
vector<int>temppath,path;
void dj(){
fill(d,d+MAXV,INF);
d[s]=0;
for(int i=0;i<n;i++){
int MIN=INF,u=-1;
for(int j=0;j<n;j++){
if(vis[j]==false&&d[j]<MIN){
MIN=d[j];
u=j;
}
}
if(u==-1) return;
vis[u]=true;
for(int v=0;v<n;v++){
if(vis[v]==false&&G[u][v]!=INF){
if(d[v]>d[u]+G[u][v]){
d[v]=d[u]+G[u][v];
pre[v].clear();
pre[v].push_back(u);
}else if(d[v]==d[u]+G[u][v]){
pre[v].push_back(u);
} }
}
}
}
void DFS(int v){
if(v==s){
temppath.push_back(v);
int tempcost=0;
for(int i=temppath.size()-1;i>0;i--){
int id=temppath[i],idnext=temppath[i-1];
tempcost+=cost[id][idnext];
}
if(tempcost<mincost){
mincost=tempcost;
path=temppath;
}
temppath.pop_back();
return;
}
temppath.push_back(v);
for(int i=0;i<pre[v].size();i++)
DFS(pre[v][i]);
temppath.pop_back();
}
int main(){
cin>>n>>m>>s>>e;
int a,b,c,dd;
fill(G[0],G[0]+MAXV*MAXV,INF);
fill(cost[0],cost[0]+MAXV*MAXV,INF);
for(int i=0;i<m;i++){
cin>>a>>b>>c>>dd;
G[a][b]=G[b][a]=c;
cost[a][b]=cost[b][a]=dd;
}
dj();
DFS(e);
for(int i=path.size()-1;i>=0;i--)
cout<<path[i]<<" ";
cout<<d[e]<<" "<<mincost;
}

  

关于该算法的题目和思想后续还会更新

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

  1. 算法-迪杰斯特拉算法(dijkstra)-最短路径

    迪杰斯特拉算法(dijkstra)-最短路径 简介: 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中 ...

  2. Dijkstra求最短路径

    单源点的最短路径问题:给定带权有向图G和源点V,求从V到G中其余各顶点的最短路径 Dijkstra算法描述如下: (1)用带权的邻接矩阵arcs表示有向图,arcs[i][j]表示弧<vi,vj ...

  3. NYOJ 1248 海岛争霸(Dijkstra变形——最短路径最大权值)

    题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=1248 描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比 ...

  4. POJ 2253 Frogger(Dijkstra变形——最短路径最大权值)

    题目链接: http://poj.org/problem?id=2253 Description Freddy Frog is sitting on a stone in the middle of ...

  5. POJ 3790 最短路径问题(Dijkstra变形——最短路径双重最小权值)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3790 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你 ...

  6. Dijkstra求最短路径&例题

    讲了半天好像也许maybe听懂了一点,先写下来233 先整理整理怎么存(开始绕) 最简单的是邻接矩阵存,但是开到10000*10000就MLE了,所以我们用链式前向星存(据说是叫这个名字吧) 这是个什 ...

  7. Dijkstra算法 - 最短路径算法

    2017-07-26 22:30:45 writer:pprp dijkstra算法法则:设置顶点集合S,首先将起始点加入该集合,然后根据起始点到其他顶点的路径长度, 选择路径长度最小的顶点加入到集合 ...

  8. POJ 2387 Til the Cows Come Home Dijkstra求最短路径

    Til the Cows Come Home Bessie is out in the field and wants to get back to the barn to get as much s ...

  9. Dijkstra算法——最短路径(转)

    转自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html Dijkstra算法 1.定义概览 Dijkstra(迪杰斯 ...

随机推荐

  1. CodeForces 347B Fixed Points (水题)

    题意:给定 n 数,让你交换最多1次,求满足 ai = i的元素个数. 析:很简单么,只要暴力一遍就OK了,先把符合的扫出来,然后再想,最多只能交换一次,也就是说最多也就是加两个,然后一个的判,注意数 ...

  2. Hadoop压缩之CompressionCodecFactory

    1.CompressionCodecFactory简介 当在读取一个压缩文件的时候,可能并不知道压缩文件用的是哪种压缩算法,那么无法完成解压任务.在Hadoop中,CompressionCodecFa ...

  3. Underscore.js实用插件

    Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象. 他解决了这个问题:“如果我面对一个空白的 HTML ...

  4. Currying and Uncurrying Js

    //反科里化Function.prototype.uncurrying = function() { var _this = this; return function() { return Func ...

  5. SciTE编写lua的快捷键整理

    SciTE快捷键整理 常用键整理: Ctrl + Q: 多行注释 Ctrl + L:删除一行或多行 Ctrl+T :和上一行换位置 Ctrl+D :复制高亮选中字符. 如果没有高亮选择字符, 则复制光 ...

  6. 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释

    建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...

  7. Java知多少虚拟机(JVM)以及跨平台原理

    相信大家已经了解到Java具有跨平台的特性,可以“一次编译,到处运行”,在Windows下编写的程序,无需任何修改就可以在Linux下运行,这是C和C++很难做到的. 那么,跨平台是怎样实现的呢?这就 ...

  8. .net 委托的简化语法

    1. 不需要构造委托对象 ThreadPool.QueueUserWorkItem:通过线程池 public static void WorkItem() { ThreadPool.QueueUser ...

  9. 爬虫开发11.scrapy框架之CrawlSpider操作

    提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...

  10. 1.Javascript简介

    web前端有三层: HTML:从语义的角度,描述页面的结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) 历史背景介绍 布兰登 艾奇 199 ...