[SPFA] 最短路 HDU图论01

最短路

Time Limit : 5000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 140   Accepted Submission(s) : 74
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

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条商店到赛场的路线。

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

#include <bits/stdc++.h>
using namespace std;
int n, m;
const int maxn = 10000;
int d[maxn];  //距离
int u[maxn], v[maxn], w[maxn], first[maxn], Next[maxn];  //边的信息
int T = 0;   //标记边的编号
void add ( int a, int b, int s ) //建图
{
	u[T] = a;
	v[T] = b;
	w[T] = s;
	Next[T] = first[a];
	first[a] = T; //邻接表
	T++;
}
void spfa()  //优化的bellman
{
	bool vis[maxn];
	memset ( vis, 0, sizeof ( vis ) );
	//vis标记是否在队列中
	for ( int i = 0; i < n; i++ ) d[i] = 1e9;
	d[0] = 0;
	queue<int>q;   //用stack和queue时间复杂度不同
	q.push ( 0 );  //起点
	vis[0] = 1;
	while ( !q.empty() )  //队列为空,不可继续松弛
	{
		int &e = q.front();   //引用
		q.pop();   //e为点的编号
		vis[e] = 0;
		for ( int t = first[e]; t != -1; t = Next[t] )  //t为边的编号
		        if ( d[v[t]] > d[e] + w[t] )
			{  //v[t]=边t的终点,e=边t的起点, w[t]=边长
				d[v[t]] = d[e] + w[t];  //更新最短路
				if ( !vis[v[t]] )  //如果不在队列中
				{
					q.push ( v[t] );
					vis[v[t]] = 1;
				}
			}
	}
	printf("%d\n",d[n-1]);
}
int main()
{
	while ( ~scanf ( "%d%d", &n, &m ) && n && m )
	{
		T = 0;  //边的编号初始化为从0开始
		memset ( first, -1, sizeof ( first ) );  //邻接表初始化
		for ( int i = 0; i < m; i++ )
		{
			int a, b, s;
			scanf ( "%d%d%d", &a, &b, &s );
			add ( a - 1, b - 1, s );  //点的编号为1~n,设为从0~n-1
			add ( b - 1, a - 1, s );  //无向图
		}
		spfa();
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值