图的最短路径Dijkstra
#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 ; }
#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 ;
}
#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的更多相关文章
- c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法
c/c++ 图的最短路径 Dijkstra(迪杰斯特拉)算法 图的最短路径的概念: 一位旅客要从城市A到城市B,他希望选择一条途中中转次数最少的路线.假设途中每一站都需要换车,则这个问题反映到图上就是 ...
- Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- 图的最短路径——dijkstra算法和Floyd算法
dijkstra算法 求某一顶点到其它各个顶点的最短路径:已知某一顶点v0,求它顶点到其它顶点的最短路径,该算法按照最短路径递增的顺序产生一点到其余各顶点的所有最短路径. 对于图G={V,{E}};将 ...
- 图的最短路径-----------Dijkstra算法详解(TjuOj2870_The Kth City)
做OJ需要用到搜索最短路径的题,于是整理了一下关于图的搜索算法: 图的搜索大致有三种比较常用的算法: 迪杰斯特拉算法(Dijkstra算法) 弗洛伊德算法(Floyd算法) SPFA算法 Dijkst ...
- 数据结构与算法-图的最短路径Dijkstra
一 无向图单源最短路径,Dijkstra算法 计算源点a到图中其他节点的最短距离,是一种贪心算法.利用局部最优,求解全局最优解. 设立一个visited访问和dist距离数组,在初始化后每一次收集一 ...
- 带权图的最短路径算法(Dijkstra)实现
一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...
- C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)
1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...
- 图的最短路径---迪杰斯特拉(Dijkstra)算法浅析
什么是最短路径 在网图和非网图中,最短路径的含义是不一样的.对于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径. 对于网图,最短路径就是指两顶点之间经过的边上权值之和最 ...
- 数据结构(C#):图的最短路径问题、(Dijkstra算法)
今天曾洋老师教了有关于图的最短路径问题,现在对例子进行一个自己的理解和整理: 题目: 要求:变成计算出给出结点V1到结点V8的最短路径 答: 首先呢,我会先通过图先把从V1到V8的各种路径全部计算下来 ...
随机推荐
- Android中Webview使用经验总结
很早前就喜欢在Android中使用Webview组件结合JS来做应用,总结了一些不错的小经验,在这里持续更新,自己备忘,也希望给其他需要的同学一些参考- 1.添加权限 要用Webview,确认你在** ...
- C# Winform 最大化后 任务栏还显示解决
//最大化 this.WindowState = FormWindowState.Maximized; //窗体最大化时 非全屏 不会遮盖任务栏 //去掉标题栏 this.FormBorderStyl ...
- PHP 之二位数组根据某个字段排序封装
/** * @param $array * @param $keys * @param string $sort * @return array */ function arraySort($arra ...
- JavaScript ES 数组系列
正文从这开始- ECMAScript 5.1 中提供的数组方法 其中部分方法,ECMAScript 3 就出现了,但是本文不再细分. ECMA-262/5.1 规范:https://www.ecma- ...
- Swoole 源码分析——Server模块之TaskWorker事件循环
swManager_start 创建进程流程 task_worker 进程的创建可以分为三个步骤:swServer_create_task_worker 申请所需的内存.swTaskWorker_in ...
- vue 瀑布流实现
<div class="myWrite" v-if="list.length==0"> - 这个福宝有点懒哦 - </div> < ...
- Spring Data Jpa-动态查询条件
/** * * 查看日志列表-按照时间倒序排列 * * @author: wyc * @createTime: 2017年4月20日 下午4:24:43 * @history: * @return L ...
- [转]十五天精通WCF——第三天 client如何知道server提供的功能清单
通常我们去大保健的时候,都会找姑娘问一下这里能提供什么服务,什么价格,这时候可能姑娘会跟你口述一些服务或者提供一份服务清单,这样的话大 家就可以做到童嫂无欺,这样一份活生生的例子,在wcf中同样是一 ...
- Unity查找脚本被哪些Perfab或场景引用
Unity中查找脚本被哪些Prefab或场景引用 Unity中有个Find References In Scene的功能,可是仅仅能查找在当前场景中的引用. 假设发现某个脚本不知道被挂在哪个Prefa ...
- Python获取当前系统时间
Python获取当前系统时间 import time #返回当前时间 def GetNowTime(): return time.strftime("%Y-%m-%d %H:%M:% ...