zoukankan      html  css  js  c++  java
  • 最短路径之——Dijkstra算法(转)

    Dijkstra算法适用于求某源点到其他顶点的最短路径问题,下面是代码。

    文件"graph.h"

    #include<iostream>
    #include<string>
    using namespace std;
    
    const int MAX=99999;
    const int MAX_VEX_NUM=20;
    class MGraph
    {
    private:
    	string vexs[MAX_VEX_NUM];//顶点数组
    	int arcs[MAX_VEX_NUM][MAX_VEX_NUM];//邻接矩阵
    	int vexnum;//顶点数
    	int arcnum;//边数
    public:
    	void Create_MG()
    	{
    		int i,j,k;
    		cout<<"输入图的顶点数和边数:";
    		cin>>vexnum>>arcnum;
    		cout<<"输入各个顶点的民称:";
    		for(i=0;i<vexnum;i++)
    			cin>>vexs[i];
    		
    		for(i=0;i<vexnum;i++)
    			for(int j=0;j<vexnum;j++)
    				arcs[i][j]=MAX;
    		//上面是初始化邻接矩阵
    		
    		for(k=0;k<arcnum;k++)
    		{
    			cout<<"输入每条边对应的始点和终点以及该边的权值:";
    			string v1,v2;
    			int w;
    			cin>>v1>>v2>>w;
    			i=Locate_Vex(v1);
    			j=Locate_Vex(v2);			
    		
    			while(i<0|| i>vexnum-1 || j<0 || j>vexnum-1)
    			{
    				cout<<"结点位置输入错误,重新输入: ";
    				cin>>v1>>v2>>w;
    				i=Locate_Vex(v1);
    				j=Locate_Vex(v2);	
    			}
    			
    			arcs[i][j]=w;
    		}
    		cout<<"图构造完成"<<endl;
    	}
    
    	int Locate_Vex(string x)  //用于确定顶点在顶点数组中的位置
    	{
    		for(int k=0;vexs[k]!=x;k++);
    		return k;
    	}
    	
    	/*---------------------------------------------------------
    	/ 用迪杰斯特拉(Dijkstra)算法求源点到其他各个顶点的最短路径
    	/ 用数组Dist[i]表示当前所找到的从源点v到每个终点vi的最短路径
    	/ 长度,初始化时,如果v到vi有弧直接连接,那么Dist[i]为权值,否
    	/ 则就为一个很大的值(99999...)。下面介绍下算法的过程:
    	/ 集合Final[]为已找到的从v出发的最短路径的终点的集合,初始
    	/ 状态只有源点一个顶点。
    	/ (1)初始化Dist[]数组,然后在Dist[]中选择最小的一个,
    	/ 将其终点并入S中。(2)修改从v出发到集合V-Final上任一顶点Vk
    	/ 可达的最短路径长度,如果Dist[j]+arcs[j][k]<Dist[k],
    	/ 则修改Dist[k]=Dist[j]+arcs[j][k]。重复(1)、(2)直到
    	/ Final[]包含全部V中顶点为止。
    	/ path[]记录终点的上一个顶点的位置.
    	/--------------------------------------------------------*/
    	
    	void Dijks_Short_Path(int v,int path[],int Dist[])
    	{
    		int min,u;
    		bool Final[MAX_VEX_NUM];
    		for(int i=0;i<vexnum;i++)
    		{
    			Final[i]=false;
    			Dist[i]=arcs[v][i];
    			if(i!=v && arcs[v][i]<MAX)
    				path[i]=v;
    			else
    				path[i]=-1;
    		}
    		Final[v]=true; //Final[]中初始状态只有V
    
    		for(i=1;i<vexnum;i++)
    		{
    			min=MAX;
    			for(int w=0;w<vexnum;w++)
    				if(!Final[w])
    					if(Dist[w]<min)
    					{
    						u=w;
    						min=Dist[w];
    					}
    			if(min==MAX)
    				return;
    			Final[u]=true; //找到离v最近的点,并加入Final
    			for(w=0;w<vexnum;w++)
    				if(!Final[w] && (min+arcs[u][w]<Dist[w]))
    				{
    					//修改Dist[w]和path[w]
    					Dist[w]=min+arcs[u][w];
    					path[w]=u;
    				}
    		}
    	}
    
    	void Print(int Dist[],int path[],int v)
    	{
    		int a[10],c,j;
    		cout<<"从源点"<<vexs[v]<<"到其他各个顶点的最短路径长度如下:"<<endl;
    		for(int i=1;i<vexnum;i++)
    		{
    			if(Dist[i]<MAX)
    				cout<<vexs[v]<<"->"<<vexs[i]<<"  "<<Dist[i]<<endl;
    			else
    				cout<<vexs[v]<<"和"<<vexs[i]<<"之间不存在路径连通"<<endl;
    		}
    
    		//利用path[]数组的特点,依次回溯找到源点,将其输出就是路径的过程了
    		for(i=1;i<vexnum;i++)
    			if(Dist[i]<MAX)
    			{
    				cout<<"从源点到"<<vexs[v]<<"到顶点"<<vexs[i]<<"的最短路径为:";
    				j=i;
    				c=0;
    				while(path[j]!=-1)
    				{
    					a[c]=path[j];
    					j=path[j];
    					c++;
    				}
    				for(j=c-1;j>=0;j--)
    					cout<<vexs[a[j]]<<"->";
    				cout<<vexs[i]<<endl;
    			}
    
    	}
    };

    文件"main.cpp"

    #include"graph.h"
    
    int main()
    {
    	MGraph G;
    	G.Create_MG();
    
    	int Dist[20];
    	int path[20];
    
    	cout<<"输入源点:";
    	int v;
    	cin>>v;
    	cout<<"_____求源点到其他顶点的最短路径____"<<endl;
    	G.Dijks_Short_Path(v,path,Dist);
    	cout<<endl;
    	G.Print(Dist,path,v);
    	return 0;
    }
    

    输入和输出结果:

    输入图的顶点数和边数:6 8
    输入各个顶点的民称:v1 v2 v3 v4 v5 v6
    输入每条边对应的始点和终点以及该边的权值:v1 v3 10
    输入每条边对应的始点和终点以及该边的权值:v1 v5 30
    输入每条边对应的始点和终点以及该边的权值:v1 v6 100
    输入每条边对应的始点和终点以及该边的权值:v2 v3 5
    输入每条边对应的始点和终点以及该边的权值:v3 v4 50
    输入每条边对应的始点和终点以及该边的权值:v5 v4 20
    输入每条边对应的始点和终点以及该边的权值:v4 v6 10
    输入每条边对应的始点和终点以及该边的权值:v5 v6 60
    图构造完成
    输入源点:0
    _____求源点到其他顶点的最短路径____
    
    从源点v1到其他各个顶点的最短路径长度如下:
    v1和v2之间不存在路径连通
    v1->v3  10
    v1->v4  50
    v1->v5  30
    v1->v6  60
    从源点到v1到顶点v3的最短路径为:v1->v3
    从源点到v1到顶点v4的最短路径为:v1->v5->v4
    从源点到v1到顶点v5的最短路径为:v1->v5
    从源点到v1到顶点v6的最短路径为:v1->v5->v4->v6
    Press any key to continue
    

      

  • 相关阅读:
    js实现好看的图案 加勒比海盗(php拍黄片)
    网站优化的几点 下
    php算法 快速排序 选择算法 冒泡算法
    javascript中null和undefined的区别
    tp3 上传图片出现上传根目录不存在!请尝试手动创建:./Public/Uploads/ 错误解决思路
    网站优化的几点 上
    tp5框架 报错非法请求:admin/index/index
    通过response向服务器用Io流写入图片
    解决客户端向服务器写中文时乱码问题
    setInterval()设置页面5,4,3,2,1秒后跳转
  • 原文地址:https://www.cnblogs.com/math2010/p/2142035.html
Copyright © 2011-2022 走看看