最短路径基础

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值