单源最短路径 DIJ算法(无堆优化)

/* //***********************************
****************************************
    MapMin.cpp
                 By Mollnn.Fan
                 
           Using Dijkstra
****************************************
*/ //***********************************

#include <iostream>
#include <fstream>
#include <malloc.h>
#include <conio.h>
#include <cmath>

#define MAXN 1000
#define MAXI 2147483646

using namespace std;

int time;
int dist[MAXN]; //标识起始点到当前点的距离 
int prev[MAXN]; //标识当前点的路径上前一个点的标号 
int a[MAXN][MAXN]; //邻接矩阵 
ifstream fin;
ofstream fout;

int dij(int n,int v) //普通DIJ算法 
{
	bool s[MAXN];  //定义每一个点是否被使用 
	int i,j;
	for(i=0;i<n;i++) //初始化 
	{
		dist[i]=a[v][i];
		s[i]=0;
		if(dist[i]==MAXI)
			prev[i]=0;
		else
			prev[i]=v;
	}
	dist[v]=0;
	s[v]=1;
	for(i=1;i<n;++i) //从第2个点开始找起 
	{
		int t=MAXI;
		int p=v;
		for(j=0;j<n;++j) //找出距离始点最近的点 
		{
			if((!s[j])&&(dist[j]<t))
			{
				t=dist[j];
				p=j;
			}
		}
		//已经找出最近的点p,为中间点 
		s[p]=1;
		for(j=0;j<n;++j) //从中间点更新其余邻接点的最小权值 
		{
			if((!s[j])&&(a[p][j]<MAXI))
			{
				int ntmp=dist[p]+a[p][j];
				if(ntmp<dist[j])
				{
					dist[j]=ntmp;
					prev[j]=p;
				}
			}
		}
	}
}

void searchpath(int v, int u) //路径输出函数 
{
    int que[MAXN]; //将要输出的path点队列 
    int tot = 0; //循环变量 
    que[tot] = u+1; //队列起始位置设为终点 
    ++tot;
    int tmp = prev[u]; //定义临时变量tmp,设置值为终点的前一个点 
    while(tmp != v) //当临时变量值不等于起始点的时候继续循环 
    {
        que[tot] = tmp+1; //输出当前点到队列 
        tot++; //循环变量递增 
        tmp = prev[tmp]; //取出当前点的前一个点 
    }
    que[tot] = v+1; //输出起始点到队列,结束路径 
    for(int i=tot; i>=0; --i) //逆序输出队列 
        if(i != 0)
            fout << que[i] << " ";
        else
            fout << que[i];
    return;
}

int main()
{
	time=0;
	
	fin.open("mapmin.in");
	fout.open("mapmin.out");
	
	int n,m;
	int end;
	fin>>n>>m>>end;
	
	--end;
	
	int i,j;
	int pa,pb,t;
	
	for(i=0;i<MAXN;++i)
	{
		for(j=0;j<MAXN;++j)
		{
			a[i][j]=MAXI;
		}
		dist[i]=MAXI;
	}
	
	for(i=0;i<m;i++)
	{
		fin>>pa>>pb>>t;
		--pa;
		--pb;
		if(t<a[pa][pb])
		{
			a[pa][pb]=t;
			a[pb][pa]=t;
		}
	}
	
	dij(n,0);
 
	
	fout<<dist[end]<<endl;
	searchpath(0,end);
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值