最短路径基础

来源:互联网 发布:下载压缩解压软件 编辑:程序博客网 时间:2024/05/29 04:19

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会超intint 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

1 0
原创粉丝点击