#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. Ansible实现zabbix服务器agent端批量部署

    项目需求:由于搭建zabbix,需要每台服务器都需要安装监控端(agent)正常的的操作是一台一台去安装,这样确实有点浪费时间,这里为大家准备了一款开源 的自动化运维工具Ansible,相信大家也很熟 ...

  2. java基本类型和包装类型的区别以及object的公共方法

    Java的类型分为两部分,一个是基本类型(primitive),如int.double等八种基本数据类型: 一.基本数据类型: byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节 ...

  3. 初学者对ASCII编码、Unicode编码、UTF-8编码的理解

    最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是 255(二进制 11111111=十进制 255),如果要表示更大的整数,就必须用更多的字节. ...

  4. C++数组查重

    今天课上实验课,遇到一道题目,需要查找一个数组中出现次数最多的元素和次数,并且输出.第一次用struct模拟字典,十分麻烦而且复杂度是O(n*n).其实,运用转化的思想,可以先将其排序,然后再查找即可 ...

  5. emacs 定制进缩风格

    纵览 emacs 文档中描述,进缩风格实现只需要两步:第一步,根据内容与上下文找到对应的进缩风格的类别:第二步,依据进缩风格决定的表达式锚点的进缩偏移.下面我们对 cc-mode 风格定制加以说明. ...

  6. PAT 1034. Head of a Gang

    1034. Head of a Gang (30) One way that the police finds the head of a gang is to check people's phon ...

  7. noip模拟赛 Chtholly Nota Seniorious

    题目背景 大样例下发链接: https://pan.baidu.com/s/1nuVpRS1 密码: sfxg こんなにも.たくさんの幸せをあの人に分けてもらった だから.きっと 今の.私は 谁が何と ...

  8. 搭建LVS+Keepalived负载均衡集群

    这两天学习了LVS+Keepalived负载均衡的搭建.网上的教程非常多,可是动起手来遇到不少问题. 如今把自己的搭建过程以及遇到的一些问题给分享下. 硬件环境: Macbook 8G内存.250G ...

  9. array_change_key_case()

    定义和用法 array_change_key_case() 函数将指定数组的所有的键进行大小写转换. 如果数组的键(索引)为数字则不发生变化.如果未提供第二个参数,则默认转换为小写. 语法 array ...

  10. 申请Letencrypt的免费证书文件-nginx

    1.前言 Let's Encrypt是国外一个公共的免费SSL项目,由 Linux 基金会托管,它的来头不小,由Mozilla.思科.Akamai.IdenTrust和EFF等组织发起,目的就是向网站 ...