HDU 2544 最短路 <裸地迪杰斯特拉算法>
HDU 2544 最短路 <裸地迪杰斯特拉算法>
最短路
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 42854 Accepted Submission(s): 18789
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
Sample Output
3 2
Source
UESTC 6th Programming Contest Online
思路:
这道题是一道裸的迪杰特斯拉算法,刚学会,第一次写!在这里写一下迪杰特斯拉算法的总结吧:
迪杰特斯拉算法不能有负的权值的路,必须已知起点和终点,并且给你了许多对点的距离,让你求起点到终点的距离!
简单的总结一下prim算法和迪杰特斯拉算法之间的区别:
prim算法是已知很多对点之间的距离,让你求将所有的点连接起来的最短的路的长度!prim算法不需要知道起点和终点,它的目的是让求将所有的点连起来的最短的路,
而迪杰斯特拉算法是求两个给定的点之间的最短的距离!prim算法最终生成的是一颗最小生成树,而迪杰特斯拉算法最终生成的只是这棵树的一个树枝;他们在代码方面就只
有在数据更新的时候有所不同,在数据更新的时候prim算法是更新到集合里面任意一点的距离最短的距离就是他目前的距离,而迪杰斯特拉算法是每次都更新到源点(起点)
的距离的最小的值,大致我知道的区别就这么多,等下次深入学后再详细总结吧!
代码:
//这一次是第一次用map函数,感觉map函数好强大! #include <stdio.h> #include <string.h> #include<iostream>//这个函数名也必须有 #include <map> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f int d[155][155]; int dis[155]; int vis[155]; int m; char x[35],y[35]; int t; map<string,int>mp;//因为在main函数里面还要用到这个容器,所以要定义在函数外面 void init() { mp.clear();//在这里面清零就行了(将所有的元素删除就OK了!) getchar();//要注意字符型前面要加上getchar(); scanf("%s%s",x,y); mp[x]=1;//下表从1开始! t=2; while(!mp[y])//刚开始没有考虑起点和终点重合,一定要记住有可能重合 { mp[y]=t++;//所以这一点本能写成mp[y]=2 ; } memset(d,INF,sizeof(d)); memset(vis,0,sizeof(vis)); char a[35],b[35]; int c; for(int i=1;i<=m;i++) { getchar(); scanf("%s%s%d",a,b,&c); if(!mp[a])//当与前面的字符串不相同的时候,要将字符串进行编号 { mp[a]=t++;//否则就不用编号就行了! } if(!mp[b]) { mp[b]=t++; } if(d[mp[a]][mp[b]]>c)//字符串进行过编号之后,就可以像一般的数字一样进行操作了! { d[mp[b]][mp[a]]=d[mp[a]][mp[b]]=c; } } for(int i=1;i<t;i++) { dis[i]=d[1][i]; } dis[1]=0; vis[1]=1; } void dijkstra() { int min,k; for(int i=1;i<t;i++) { min=INF; for(int j=1;j<t;j++) { if(!vis[j]&&dis[j]<min) { min=dis[j]; k=j; } } if(min==INF) break; vis[k]=1; for(int j=1;j<t;j++) { if(!vis[j]&&dis[j]>dis[k]+d[k][j]) { dis[j]=dis[k]+d[k][j]; } } } } int main() { while(scanf("%d",&m)&&(m!=-1)) { init(); dijkstra(); if(dis[mp[y]]==INF)//刚开始没有考虑起点和终点重合,一定要记住有可能重合 printf("-1\n"); else printf("%d\n",dis[mp[y]]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。