Dijkstra算法

代码:

// Dijkstra.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<cmath>
#include<math.h>
#include<vector>
#include<list>
#define MAX pow(2.0,20.0)
#define NUM 6

using namespace std;
/*
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::list;
using std::iterator;
*/

void CreateGraph(double G[NUM][NUM]);
void Dijkstra(double G[NUM][NUM],int s);

struct DK
{
	bool visit;
	double distance;
	int prenode;
	list<int> path;//记录路径
};

int main(int argc,char* argv[])
{
	double Graph[NUM][NUM];
	int s=0;
	//初始化都是无穷大
	for(size_t t1=0;t1<NUM;++t1)
	{
		for(size_t t2=0;t2<NUM;++t2)
		{
			Graph[t1][t2]=MAX;
		}
	}
	cout<<"请输入源点"<<endl;
	cin>>s;
	CreateGraph(Graph);
	Dijkstra(Graph,s);

	system("pause");
	return 0;
}

void CreateGraph(double G[NUM][NUM])
{
	size_t v1=0;
	size_t v2=0;
	double w=0;//权值
	cout<<"输入顶点及权值<-1,-1,-1>结束"<<endl;
	cin>>v1>>v2>>w;
	while(v1!=-1||v2!=-1||w!=-1)
	{
		if(v1<NUM && v2<NUM)
		{
			G[v1][v2]=w;
		}
		else
		{
			cout<<"下标溢出"<<endl;
			v1=0;
			v2=0;
		}
		cin>>v1>>v2>>w;
	}
}

void Dijkstra(double G[NUM][NUM],int src)
{
	DK dis[NUM];
	double min=MAX;
	int min_node_name=0;
	int count=NUM-1;//比较n-1次
	vector<int> S;
	S.push_back(src);
	size_t t=0;
	for(t=0;t<NUM;++t)
	{
		dis[t].visit = false;
		dis[t].distance=MAX;
		dis[t].prenode=0;
	}
	t=0;
	dis[src].visit=true;
	while(t<NUM)
	{
		if(G[src][t]<MAX && src!=t)
			dis[t].distance=G[src][t];
		++t;
	}
	while(count!=0)
	{
		min=MAX;
		t=0;
		while(t<NUM)
		{
			if(!dis[t].visit && dis[t].distance<min)
			{
				min=dis[t].distance;
				min_node_name=t;
			}
			++t;
		}
		S.push_back(min_node_name);
		dis[min_node_name].visit=true; 
		vector<int>::iterator I_ite;
		I_ite=S.begin();
		size_t t1=0;
		while(I_ite!=S.end())
		{
			t1=0;//每次都要归零
			while(t1<NUM)
			{
				if(*I_ite!=src)
				{
					if(dis[*I_ite].distance+G[*I_ite][t1]<dis[t1].distance)
					{
						dis[t1].distance=dis[*I_ite].distance+G[*I_ite][t1];
						dis[t1].prenode=*I_ite;
					}
					++t1;
				}
				else
					break;
			}
			I_ite++;
		}
		--count;
	}
	/*根据各节点前驱求路径*/
	for(t=0;t!=NUM;t++)
	{
		if(dis[t].distance!=MAX)
		{
			dis[t].path.push_front(t);
			size_t st=dis[t].prenode;
			while(st!=src)
			{
				dis[t].path.push_front(st);
				st=dis[st].prenode;
			}
			dis[t].path.push_front(src);
		}
	}
	for(t=0;t!=NUM;t++)
	{
		if(dis[t].distance==MAX)
		{
			cout<<"源点V"<<src<<"到V"<<t<<"没有路径"<<endl;
		}
		else
		{
			cout<<"源点V"<<src<<"到V"<<t<<"路径是:";
			list<int>::iterator I_list=dis[t].path.begin();
			while(I_list!=dis[t].path.end())
			{
				cout<<"V"<<*I_list<<",";
				I_list++;
			}
			cout<<"最短路径为:"<<dis[t].distance<<endl;
		}
	}
}

结果:


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值