taxi
时间限制:1秒 内存限制: 128 MB
描述
寒假里,小呆要去位于A市的皮球家拜年。小呆来到A市的车站,买了一张A市的地图,他发现这里的地形非常的复杂。A市的街道一共有N个路口,M条道路,每条道路连接着两个路口,并且有各自的长度。目前,小呆所在的车站位于编号为1的路口,而皮球家所在的路口编号为N,小呆准备打出租车去,当然,路程越小,付的钱就越少。问题摆在眼前:请帮助小呆寻找一条最短路径,使得他可以花最少的钱到达皮球家。
输入
第一行有两个整数N;M,(N<=1000<=M)分别代表路口数和街道数。以下有M行用以描述各个街道,每行有三个数字P1;P2;L,分别代表此街道起点编号,此街道终点编号以及此街道的长度。保证所给的数据可以构成连通图。
输出
只要求出现一行,一个整数,说明最短路径的长度(<=maxlongint)。
输入样例
6 7
1 2 1
1 3 5
1 4 2
4 6 10
2 5 3
3 5 8
5 6 7
输出样例
11
这题是经典的最短路算法,裸到不能再裸了。作为蒟蒻的我首先默默地写了Floyd,然后才一步两步、一步两步写出Dijkstra。
Floyd就是把所有点找一遍,然后松弛操作,非常暴力。
#include<cstdio>
#include<cstdlib>
#include<iostream>
int g[1001][1001],maxint=1073741824;//注意开成2147483647会超int
int main(){
int n,m,w,x,y;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++) g[i][j]=maxint;
for (int i=1;i<=m;i++) {
scanf("%d%d%d",&x,&y,&w);
g[x][y]=g[y][x]=w;
}
for (int k=1;k<=n;k++)//残暴的枚举中间点
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (g[i][k]+g[k][j]<g[i][j]) g[i][j]=g[i][k]+g[k][j];//松弛
printf("%d\n",g[1][n]);
return 0;
}
/*Floyd卡成翔自己都看不下去了,于是默默地写了DijkstraDijkstra本人理解就是基于贪心的松弛,注意不能有负权,否则会形成负权环。*/
#include<cstdio>
#include<cstdlib>
#include<iostream>
int g[1001][1001],dist[1001],hash[1001],maxint=1073741824;
int main(){
int n,m,w,min,x,y;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++) g[i][j]=maxint;
for (int i=1;i<=m;i++) {
scanf("%d%d%d",&x,&y,&w);
g[x][y]=g[y][x]=w;
}
for(int i=1;i<=n;i++) dist[i]=maxint;
dist[1]=0;
for(int i=1;i<=n;i++) {
min=maxint;
int j,k;
for(j=1;j<=n;j++) if(!hash[j]&&dist[j]<min){
min=dist[j];
k=j;
}
hash[k]=j;
for(int j=1;j<=n;j++) if(g[k][j]!=0&&!hash[j]&&dist[j]>dist[k]+g[k][j])
dist[j]=dist[k]+g[k][j];
}
printf("%d",dist[n]);
return 0;
}
初学者可以看看这个Dijkstra的详解,这里讲的比较详细。 http://wenku.baidu.com/link?url=li6Ep5KXCG4k4ii7ddiITYQj1WtZD832CAVzL-ymV5OwULdlYSmXBO6A_Xs0xqnh8wNtQvSZUDQUfZK3CWh5tGm2dv91OYjExMaZZBCfeye