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
    

      

  • 相关阅读:
    堆栈学习
    需要阅读的书籍
    Rust Book Lang Ch.19 Fully Qualified Syntax, Supertraits, Newtype Pattern, type aliases, never type, dynamic sized type
    Rust Lang Book Ch.19 Placeholder type, Default generic type parameter, operator overloading
    Rust Lang Book Ch.19 Unsafe
    Rust Lang Book Ch.18 Patterns and Matching
    Rust Lang Book Ch.17 OOP
    Rust Lang Book Ch.16 Concurrency
    Rust Lang Book Ch.15 Smart Pointers
    HDU3966-Aragorn's Story-树链剖分-点权
  • 原文地址:https://www.cnblogs.com/math2010/p/2142035.html
Copyright © 2011-2022 走看看