最短路径——Dijkstra算法HDU Today(hdu2112)

关于本题的floyd解法:http://blog.csdn.net/sm9sun/article/details/53282826

上篇博文介绍了floyd解决最短路径的方法,然而由于floyd极大的时间开销O(n^3)导致其应用领域并不是很广

本文再介绍一个最短路径的算法——Dijkstra算法

Dijkstra算法是典型的算法。Dijkstra算法是很有代表性的算法。Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

首先,引进一个辅助向量D,它的每个分量D表示当前所找到的从始点v到每个终点vi的最短路径的长度。如D[3]=2表示从始点v到终点3的路径相对最小长度为2。这里强调相对就是说在算法过程中D的值是在不断逼近最终结果但在过程中不一定就等于最短路径长度。它的初始状态为:若从v到vi有弧,则D为弧上的权值;否则置D为∞。显然,长度为 D[j]=Min{D | vi∈V} 的路径就是从v出发的长度最短的一条最短路径。此路径为(v,vj)。 那么,下一条长度次短的最短路径是哪一条呢?假设该次短路径的终点是vk,则可想而知,这条路径或者是(v,vk),或者是(v,vj,vk)。它的长度或者是从v到vk的弧上的权值,或者是D[j]和从vj到vk的弧上的权值之和。 一般情况下,假设S为已求得最短路径的终点的集合,则可证明:下一条最短路径(设其终点为X)或者是弧(v,x),或者是中间只经过S中的顶点而最后到达顶点X的路径。因此,下一条长度次短的最短路径的长度必是D[j]=Min{D | vi∈V-S} 其中,D或者是弧(v,vi)上的权值,或者是D[k](vk∈S)和弧(vk,vi)上的权值之和。迪杰斯特拉算法描述如下: 1)arcs表示弧上的权值。若不存在,则置arcs为∞(在本程序中为MAXCOST)。S为已找到从v出发的最短路径的终点的集合,初始状态为空集。那么,从v出发到图上其余各顶点vi可能达到的最短路径长度的初值为D=arcs[Locate Vex(G,v),i] vi∈V 2)选择vj,使得D[j]=Min{D | vi∈V-S} 3)修改从v出发到集合V-S上任一顶点vk可达的最短路径长度。

以上为百科对于Dijkstra的描述,其实通俗一点说,就是先采取贪心的思路,先选择一个接下来准备连接的权值最小的点j,然后看看是否存在某个k点,满足到j再到k的值要小于直接到k本身,如果有,优化路径。看起来原理差不太多,Dijkstra是贪心的一个一个节点添加,加一个点刷一次路径。。而floyd是把所有已经连接的路径都标出来,再通过不等式比较来优化路径。

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2112

题目描述:

经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强。这时候,XHD夫妇也退居了二线,并在风景秀美的诸暨市浬浦镇陶姚村买了个房子,开始安度晚年了。
这样住了一段时间,徐总对当地的交通还是不太了解。有时很郁闷,想去一个地方又不知道应该乘什么公交车,在什么地方转车,在什么地方下车(其实徐总自己有车,却一定要与民同乐,这就是徐总的性格)。
徐总经常会问蹩脚的英文问路:“Can you help me?”。看着他那迷茫而又无助的眼神,热心的你能帮帮他吗?
请帮助他用最短的时间到达目的地(假设每一路公交车都只在起点站和终点站停,而且随时都会开)。
Input
输入数据有多组,每组的第一行是公交车的总数N(0<=N<=10000);
第二行有徐总的所在地start,他的目的地end;
接着有n行,每行有站名s,站名e,以及从s到e的时间整数t(0<t<100)(每个地名是一个长度不超过30的字符串)。
note:一组数据中地名数不会超过150个。
如果N==-1,表示输入结束。
Output
如果徐总能到达目的地,输出最短的时间;否则,输出“-1”。
Sample Input
6
xiasha westlake
xiasha station 60
xiasha ShoppingCenterofHangZhou 30
station westlake 20
ShoppingCenterofHangZhou supermarket 10
xiasha supermarket 50
supermarket westlake 10
-1
Sample Output
50
Hint:
The best route is:
xiasha->ShoppingCenterofHangZhou->supermarket->westlake

#include<stdio.h>
#include<string.h>
#define INF 999999999
int V_nMapValue[155][155];
int  C_nPointId;
char N_sPointName[155][40];


int fmin(int a,int b) 
{
	return a<b?a:b;
}

void Init()
{
	int i,j;

    for(i=0;i<155;i++)
    for(j=0;j<155;j++)
    V_nMapValue[i][j]=(i==j)?0:INF;
}

int Get_PointId_by_PointName(char *s)
{
    int i;
    for(i=0;i<C_nPointId;i++)
    if(!strcmp(N_sPointName[i], s))
    return i;
   
    strcpy(N_sPointName[C_nPointId],s);
    C_nPointId++;
    return C_nPointId-1;  
}

void Dijkstra()
{
    int Z_vis[155], i,j,k;
    memset(Z_vis, 0, sizeof(Z_vis));

    
    for(i=0;i<C_nPointId;i++)
    {
        int Id_temp=0,Value_temp=INF;
        
        for(j=0;j<C_nPointId;j++)           //最短连接点 
        if(!Z_vis[j]&&V_nMapValue[0][j]<Value_temp)
        {
        Id_temp=j;
        Value_temp=V_nMapValue[0][j];
        }
                 
        if(Value_temp==INF)                     //没有合适的新路径 
		break;
        
        Z_vis[Id_temp]=1;                       //选入新点 
        
        for(k=0;k<C_nPointId;k++)               //优化路径 
        V_nMapValue[0][k]=fmin(V_nMapValue[0][k],V_nMapValue[0][Id_temp]+V_nMapValue[Id_temp][k]);

    }
}

void Floyd()
{
	int i,j,k;
	
	//存在一个k 使aik+akj路径小于aij 
	for(k=0;k<C_nPointId;k++)
	for(i=0;i<C_nPointId;i++)
	for(j=0;j<C_nPointId;j++)
	V_nMapValue[i][j]=fmin(V_nMapValue[i][j],V_nMapValue[i][k]+V_nMapValue[k][j]);	
}






int main()
{
    int n,i,j;
    while(~scanf("%d",&n)&&n!=-1)
    {
    
       Init();                  
  
        char N_sStPoint[40], N_sEnPoint[40];
		scanf("%s%s",&N_sStPoint, &N_sEnPoint);
        strcpy(N_sPointName[0], N_sStPoint);
        strcpy(N_sPointName[1], N_sEnPoint);
        C_nPointId = 2;
        
		
		
		char Point_a_name[40],Point_b_name[40];
        int  Point_a_id,Point_b_id,Value_By_ab;
        for(i=0;i<n;i++)
        {
            scanf("%s%s%d",&Point_a_name,&Point_b_name,&Value_By_ab);
            Point_a_id = Get_PointId_by_PointName(Point_a_name);
            Point_b_id = Get_PointId_by_PointName(Point_b_name);
            V_nMapValue[Point_a_id][Point_b_id] = V_nMapValue[Point_b_id][Point_a_id] = Value_By_ab;
        }
        
        
        if(!strcmp(N_sStPoint, N_sEnPoint))
        {
            printf("0\n");
            continue;
        }
        
        /*
        for(i=0;i<C_nPointId;i++)
        for(j=0;j<C_nPointId;j++)
        printf("%d%c",V_nMapValue[i][j],j==C_nPointId-1?'\n':' ');
        */
        
        
        Dijkstra();
        
        
        //Floyd();
        if(V_nMapValue[0][1]==INF)
            printf("-1\n");
        else
            printf("%d\n",V_nMapValue[0][1]);
    }
    return 0;
}

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/sm9sun/article/details/53283791
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞