1. 程式人生 > >HDU 2544(最短路徑 SPFA 演算法模板)

HDU 2544(最短路徑 SPFA 演算法模板)

F - 最短路 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Input

Output

Sample Input

Sample Output

Hint

Description

某省自從實行了很多年的暢通工程計劃後,終於修建了很多路。不過路多了也不好,每次要從一個城鎮到另一個城鎮時,都有許多種道路方案可以選擇,而某些方案要比另一些方案行走的距離要短很多。這讓行人很困擾。

現在,已知起點和終點,請你計算出要從起點到終點,最短需要行走多少距離。

Input

本題目包含多組資料,請處理到檔案結束。
每組資料第一行包含兩個正整數N和M(0<N<200,0<M<1000),分別代表現有城鎮的數目和已修建的道路的數目。城鎮分別以0~N-1編號。
接下來是M行道路資訊。每一行有三個整數A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城鎮A和城鎮B之間有一條長度為X的雙向道路。
再接下一行有兩個整數S,T(0<=S,T<N),分別代表起點和終點。

Output

對於每組資料,請在一行裡輸出最短需要行走的距離。如果不存在從S到T的路線,就輸出-1.

Sample Input

3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2

Sample Output

2 -1

Hint

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

思路:SPFA模板題,從起點開始,更新每個點到起點的距離,用book陣列記錄點是否在佇列中,若在佇列中,則只更新,不加入佇列,若該點通過新途徑的距離比原來的距離大,則不更新,也不加入佇列,一直操作,直到佇列結束。

程式碼如下:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<vector>
#define inf 0x3f3f3f3f 
using namespace std;
int n, m;
struct node
{
	int to, distance;
};
vector<node>g[105];
bool book[105];
int dis[105];
void myinit()
{
	memset(book, 0, sizeof(book));
	for(int i = 0; i < 105; i++)
	{
		g[i].clear();
	}
	memset(dis, inf, sizeof(dis));
}
void SPFA(int s)
{
	queue<int> q;
	q.push(s);
	book[s] = 1;//加入佇列並標記 
	while(!q.empty())
	{
		int point = q.front();
		q.pop();
		book[point] = 0;//彈出佇列並取消標記 
		for(int i = 0; i < g[point].size(); i++)
		{
			if(g[point][i].distance + dis[point] < dis[g[point][i].to])//比較 
			{
				dis[g[point][i].to] = g[point][i].distance + dis[point];//更新路徑 
				if(!book[g[point][i].to])//若該點不在佇列 
				{
					q.push(g[point][i].to);
					book[g[point][i].to] = 1;
				}
			}
			
		}
	}
}
int main()
{
	int i, j, x, y, d;
	while(scanf("%d%d", &n, &m)!=EOF &&(n || m))
	{
		myinit();
		for(i = 0; i < m; i++)
		{
			scanf("%d%d%d", &x, &y, &d);
			node n1, n2;
			n1.to = x; n1.distance = d;
			n2.to = y; n2.distance = d;
			g[x].push_back(n2);
			g[y].push_back(n1);
		}
		dis[1] = 0;
		SPFA(1);
		cout<<dis[n]<<endl;
	}
	return 0;
}