概述
最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。 算法具体的形式包括:
确定起点的最短路径问题 - 即已知起始结点,求最短路径的问题。
确定终点的最短路径问题 - 与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。
确定起点终点的最短路径问题 - 即已知起点和终点,求两结点之间的最短路径。全局最短路径问题 - 求图中所有的最短路径。
最短路径的几大常用的经典算法有:floyd算法、Dijkstra、spfa算法等。其中,floyd是最易于理解的算法,当然,其时间复杂度也是蛮尴尬的O(n^3)
首先说明一下:Floyd算法又称为插点法,对于每一对顶点i和j,看看是否存在一个顶点k使得从 i到k再到 j比已知的路径更短。如果是更新它。
把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。定义一个矩阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。
比如,要寻找从V5到V1的路径。根据D,假如D(5,1)=3则说明从V5到V1经过V3,路径为{V5,V3,V1},如果D(5,3)=3,说明V5与V3直接相连,如果D(3,1)=1,说明V3与V1直接相连。
所以说,其方法就是枚举暴力,我们可以傻瓜式的写出三个for循环就可以搞定了
//存在一个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]);
看一道例题
题目链接:
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
然后运用floyd枚举所有的点。
#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 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("0n");
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':' ');
*/
Floyd();
if(V_nMapValue[0][1]==INF)
printf("-1n");
else
printf("%dn",V_nMapValue[0][1]);
}
return 0;
}
最后
以上就是斯文黄蜂为你收集整理的最短路径——Floyd算法HDU Today(hdu2112)的全部内容,希望文章能够帮你解决最短路径——Floyd算法HDU Today(hdu2112)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复