#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. lsof command not found 解决

    有些centos 没有 lsof命令,需要安装 yum install lsof -y 使用: lsof -i:端口号

  2. HTML学习笔记之HTML5新特性

    目录 1.拖放 2.画布 3.可伸缩矢量图形 4.地理定位 5.Web 存储 6.应用缓存 7.Web Worker 1.拖放 拖放是一种常见的特性,用于抓取对象以后拖到另一个位置,它是 HTML5 ...

  3. 如何在Ubuntu16.04 中安装Linux, Nginx, MySQL, PHP (LEMP 栈)

    介绍 LEMP 栈是用来开发动态网页和web 应用程序的一系列软件集合,LEMP描述的是Linux操作系统,Nginx web 服务器,以及后端数据存储MySQL/MariaDB数据库和服务器端动态脚 ...

  4. vue中对象属性改变视图不更新问题

    常规情况下我们在vue实例的data中设置响应数据.但当数据为对象,我们增加或删除对象属性值时,视图并不触发更新,如何解决这个问题呢? let vm = new Vue{ el: '#app', da ...

  5. map put

    public class test { static Map<String, Map<String, Integer>> mapB = new HashMap<Strin ...

  6. [Usaco2014 Mar]Sabotage

    [Usaco2014 Mar]Sabotage 题目 Farmer John"s arch-nemesis, Farmer Paul, has decided to sabotage Far ...

  7. 清北学堂模拟赛d2t2 位运算2(bit)

    题目描述LYK拥有一个十进制的数N.它赋予了N一个新的意义:不考虑N的符号,将N每一位都拆开来后再加起来就是N所拥有的价值.例如数字123拥有6的价值,数字999拥有27的价值,数字-233拥有8的价 ...

  8. NFS 文件系统的搭建

    教程: 一.配置linux内核: 进入打过at91补丁的linux2.6内核源代码树的根目录 make menuconfig进入内核配置程序. 1.  Networking ---> Netwo ...

  9. mbr gpt

    超过2T硬盘的磁盘要用gpt格式,准确地说,应该是分区超过2T地硬盘要选用GPT模式. 做个小推广:程序员经常久坐,颈椎毛病比较多,特别推荐ventry颈椎保健枕

  10. [bzoj3192][JLOI2013]删除物品_树状数组_栈

    删除物品 bzoj-3192 JLOI-2013 题目大意:给你n个物品,分成2堆.所有的物品有不同的优先级.我只可以将一堆中的堆顶移动到另一个堆的堆顶.而如果当前物品是全局所有物品中优先级最高的,我 ...