Dijkstra算法的实现 C



/*!
 * @file     dijkstra.cpp
 * @Date:    2018/05/07 20:48
 * @author:  sicaolong
 * @Contact: sicaolong@163.com
 * @brief:   
 * @TODO: 
 思路:设置的变量都有 d[]用来保存最短距离;pre[]表示当前点的父节点;
visited[];用来表示当前点 有没有被访问过;


1、先初始化d[]=INF;d[v0]=0;pre[i]=i;
2、循环遍历每一个周围的点
for(int i=0;i<n;i++)
{
int u=-1;最小的值的 序号;
min=INF;
for(int j=0;j<n;j++)对其余的点进行遍历;看看是不是存在d<min;
{
if(visited[j]==false &&d[j]<min)
{
u=j;
min=d[j];
}
}
if(u==-1)看看是不是没有联通的点;如果没有联通的点直接退出;
return ;


for(int v=0;v<n;v++)遍历所有的点,看看是不是未被访问,并且距离最优
{.
if(visited[j]==false && d[u]+G[u][v]<d[v])
d[v]=d[u]+G[u][v];
pre[v]=u;

}


}


*/
#include<iostream>
#include <vector>
#include <assert.h>
using namespace std;
const int INF = 100000;
void Dijkstr(vector<vector<int>> G, int n, int v0, bool *visited, vector<int >d, vector<int>& pre);
void DFS_print(int v0, int v, vector<int>pre);
//=========main函数


void Dijkstr(vector<vector<int>> G, int n, int v0, bool *visited, vector<int >d, vector<int>& pre)
{
/*
param
n:           顶点个数
v0:           源点
G:           图的邻接矩阵
visited:         标记顶点是否已被访问
d:           存储源点s到达其它顶点的最短距离
pre:         存储从起点s到达顶点v的最短路径上v的前一个顶点 (新添加)
*/


fill(d.begin(), d.end(), INF);//给d[]数组赋值初始值为inf 无限大;
d[v0] = 0;//0点到本身的距离为0;
for (int i = 0; i < n; i++)//先将每一个点的前驱节点设置为本身;初始化;
pre[i] = i;
for (int i = 0; i < n; i++)//从0的开始循环遍历每一个点;
{
int u = -1;//找到d[u]最小的u;
int min = INF;
for (int j = 0; j < n; j++)
{
if (visited[j] == false && d[j] < min)
{
u = j;//更新找到的最小值的点;
min = d[j];
}
}
if (u == -1)
return;//找不到联通的顶点;
visited[u] = true;
for (int v = 0; v < n; v++)
{
//遍历所有的顶点,如果v未被访问并且 u能够到达v 并且 以u为中间点 会使得d[v]更小;
if (visited[v]==false&&d[u]+G[u][v]<d[v])
{
d[v] = d[u] + G[u][v];
pre[v] = u;
}
}
}
}
void DFS_print(int v0, int v, vector<int>pre)
{
if (v == v0)//什么时候结束;也就是只有一个结点的时候;或者说当前点等于起始点的时候打印;
{
cout << v0 << endl;
return;
}
DFS_print(v0, pre[v], pre);//递归分治 遍历打印;
cout << v <<" "<< endl;
}
void main()
{
int n = 6;
vector<vector<int>>G = {
{ 0, 1, INF, 4, 4, INF },
{ INF, 0, INF, 2, INF, INF },
{ INF, INF, 0, INF, INF, 1 },
{ INF, INF, 2, 0, 3, INF },
{ INF, INF, INF, INF, 0, 3 },
{ INF, INF, INF, INF, INF, 0 }
};
//vector<bool >visited(n, false);
bool *visited = new bool[n];
memset(visited, false, n);
vector<int>d(n);
vector<int>pre(n);
Dijkstr(G, n, 0, visited, d, pre);
for (auto x : d)
cout << x << " ";
cout << endl;
DFS_print(0, 5, pre);
//return 0;


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值