单源最短路径 贪心算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三单源最短路径
一、实验目的及要求
掌握贪心算法的基本思想
用c程序实现单源最短路径的算法
二、实验环境
Window下的vc 2010
三、实验内容
1、有向图与单源点最短路径
2、按路径长度非降的次序依次求各节点到源点的最短路径
3、Dijkstra算法
四、算法描述及实验步骤
设给定源点为Vs,S为已求得最短路径的终点集,开始时令S={Vs} 。当求得第一条最短路径(Vs ,Vi)后,S为{Vs,Vi} 。根据以下结论可求下一条最短路径。
设下一条最短路径终点为Vj ,则Vj只有:源点到终点有直接的弧
若定义一个数组dist[n],其每个dist[i]分量保存从Vs 出发中间只经过集合S中的顶点而到达Vi的所有路径中长度最小的路径长度值,则下一条最短路径的终点Vj必定是不在S中且值最小的顶点,
即:dist[i]=Min{ dist[k]| Vk∈V-S }
利用公式就可以依次找出下一条最短路径。
在程序中c[][]表示带权邻接矩阵, dist[]表示顶点到源点的最短路径, p[]记录顶点到源点最短路径的前驱节点, u源点,函数Way是递归的构造出最短路径的次序。
五、实验结果
程序执行的结果:
六、源代码
#include
#include
using namespace std;
#define MAX 999
void getdata(int **c,int n)
{
int i,j;
int begin,end,weight;
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
{
if(i==j)
c[i][j]=0;
else
c[i][j]=MAX;
}
}
do {
cout<<"请输入起点终点权值(-1退出):";
cin>>begin;
if(begin==-1) break;
cin>>end>>weight;
c[begin][end]=weight;
} while(begin!=-1);
}
void Dijkstra(int n,int v ,int *dist,int *prev,int **c)
{
bool s[MAX];
int i,j;
for (i=1;i<=n;i++)
{
dist[i]=c[v][i]; //从源点到各点的值
s[i]=false;
if(dist[i]==MAX) prev[i]=0; //最大值没有路径
else prev[i]=v; //前驱为源点
}
dist[v]=0;s[v]=true;
for (i=1;i<=n;i++)
{
int temp=MAX;
int u=v;
for(j=1;j<=n;j++)
if((!s[j])&&(dist[j] for (j=1;j<=n;j++) { if((!s[j])&&(c[u][j] { int newdist=dist[u]+c[u][j]; if(newdist } } } } void PrintPath(int *prev,int n,int begin,int end) { int *path=new int [n+1]; int i,m=n; bool k=true; path[end]=end; for(i=end-1;i>1;i--) { path[i]=prev[path[i+1]]; //构造路径 m--; } for (i=m;i<=end;i++) { cout< cout<<"\b\b"<<" "< } void main() { int n,i; int v=1; cout<<"请输入顶点个数:"; cin>>n; int *dist=new int [n+1]; int *prev=new int [n+1]; int **c; c=new int *[n+1]; for (i=0;i<=n;i++) { c[i]=new int [n+1]; } getdata(c,n); //获取数据 int begin=1,end; cout<<"请输入所求单源路径的起点终点:"; cin>>begin>>end; v=begin; Dijkstra(n,v,dist,prev,c); //计算路径 PrintPath(prev,n,begin,end); //输出路径system("pause"); }