#单源最短路径算法设计
问题描述:
给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从源到所有其他各顶点的最短路长度。这里路的长度是指路上各边权之和。
输入:
第一行,分别表示为 源点,顶点个数,单源路径个数。
其余各行分别表示为 起点,终点,对应权值。
如下:
1 5 7
1 2 20
1 5 50
1 4 60
2 3 30
3 5 10
4 3 40
4 5 10
输出:
点 1 到点 2 的最小距离为 20
路径为 :
1 2
点 1 到点 3 的最小距离为 50
路径为 :
1 2 3
点 1 到点 4 的最小距离为 30
路径为 :
1 4
点 1 到点 5 的最小距离为 50
路径为 :1 5
算法描述:
贪心算法的描述:
贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法的性质:
- 不同于DP:
全局最优解可以通过局部最优解来得到(这也是和动态规划的主要区别),动态规划的算法通常以自底向上的方式来解各种子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每一次的贪心选择就将所求问题简化为规模更小的子问题。 - 最优子结构:
当一个问题的最优解包含其子问题的最优解时,称此问题具有 最优子结构性质,问题的最优子结构性质是该问题可以用动态规划或者贪心算法求解的关键特征。
贪心算法的基本思路:
1.建立数学模型来描述问题。
2.把求解的问题分成若干个子问题。
3.对每一子问题求解,得到子问题的局部最优解。
4.把子问题的解局部最优解合成原来解问题的一个解。
算法设计:
(1)设置一集合S存放已经找到最短路的点的集合。
(2) 将源点并入S, 初始化源到V-S中各点的“当前最短路径”
(3) 重复如下步骤n-1次:
① 在V-S中找当前路径最短的顶点;
②找到后并入S;
③ 据此更新源到其他点的距离。
举例:
我画的有向图如下:
程序:
#include “stdafx.h”
#include
#include"stdio.h"
using namespace std;
const int max_ = 0x3f3f3f;//设置每个元素的最大有效值
int G[110][110];//设置图对应的邻接矩阵的大小
int dist[110]; //dist[i]存储源到顶点 i 的当前最短路长度
int tip[110]; //标记i号顶点是否已并入S
int pre[110]; //记录的是从源到顶点i的最短路径上i的前一个顶点。用来求出相应的最短路径
int m, n, p; //m代表路径的个数, n代表顶点的个数,p代表源,然后回溯输出路径
void traceback(int i)
{
if(pre[i] == i)
{
printf("%d", i);
}
else
{
traceback(pre[i]);
printf(" %d", i);
}
}
void out()
{
for(int i = 1; i <= n; ++i)
{
if(i != p)
{
printf(“点 %d 到点 %d 的最小距离为 %d\n”, p, i, dist[i]);
cout << “路径为 :” << endl;
traceback(i);
cout << endl;
}
}
}
void Dijkstra()
{
//初始化
for(int i = 1; i <= n; ++i)
{
dist[i] = G[p][i];
tip[i] = 0;
pre[i] = p;
}
dist[p] = 0;
tip[p] = 1;
for(int i = 1; i < n; ++i)
{
int pos, min_len = max_;
for(int i = 1; i <= n; ++i)
{
if(!tip[i] && min_len > dist[i])
{
pos = i, min_len = dist[i];
}
}
tip[pos] = 1;
for(int j = 1; j <= n; ++j)
{
if(!tip[j] && dist[j] > min_len + G[pos][j])
{
dist[j] = min_len + G[pos][j];
pre[j] = pos;
}
else
continue;
}
}
}
void in()
{
int pos1, pos2, dis;
memset(G, max_, sizeof(G));
cin>>p>>n>>m;
for(int i = 1; i <= m; ++i)
{
//scanf("%d %d %d", &pos1, &pos2, &dis);
cin >> pos1>> pos2>> dis ;
G[pos1][pos2] = dis;
}
}
int main()
{
in();
Dijkstra();
out();
system(“pause”);
}