洛谷題集——單源最短路徑(弱化版、spfa+鄰接表)

題目

給出一個有向圖,請輸出從某一點出發到所有點的最短路徑長度。

輸入格式
第一行包含三個整數 n , m , s 分別表示點的個數、有向邊的個數、出發點的編號。

接下來 m 行每行包含三個整數 u , v , w 表示一條u→v 的,長度爲 w 的邊。

輸出格式
輸出一行 n 個整數,第 i 個表示 s 到第 i 個點的最短路徑,若不能到達則輸出 231-1

輸入輸出樣例
輸入
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
輸出
0 2 4 3
洛谷測試平臺


  • SPFA 算法
    Bellman-Ford算法的隊列優化算法的別稱,通常用於求含負權邊的單源最短路徑,以及判負權環。SPFA 最壞情況下複雜度爲 O(NM)。

  • 迪傑斯特拉算法
    由荷蘭計算機科學家 狄克斯特拉於1959 年提出的,因此又叫 狄克斯特拉算法。是從一個頂點到其餘各頂點的 最短路徑算法,解決的是有向圖中最短路徑問題。迪傑斯特拉算法主要特點是以起始點爲中心向外層層擴展,直到擴展到終點爲止。 迪傑斯特拉算法 最壞情況下複雜度爲 O(NM)。可用堆進行優化,優化後O(( m+ n)log n)。(不可判負權環

本題測試數據較小,可直接採用 spfa +鄰接表解決。
關鍵點

  • 創建結構體數組
    ①、存儲第 i 個城市到達 s 城市的最短路徑。
    ②、存儲第 i 個城市可到達的(多個)城市標號及路徑長度。
  • spfa算法——隊列
    ①、將可能爲最短路徑的城市插入隊列中。
    若 i 城市到 j 城市路徑長度 + 第 i 城市到第 s 城市最短路徑 <= j 城市到第 s 城市最短路徑,則不必將 j 城市放入隊列。
#include<bits/stdc++.h>
using namespace std;
struct node1{
	int len;		//第i個城市的路徑長度 
	int end;		//通往的城市標號
}tmp;

struct node{
	vector <node1> next;	//第i個城市能通往的城市信息
	int min_dis;			//第i個城市通往s的最短路徑
}N[10010];

void bfs(int a){
	queue <int> q;
	q.push(a);
	while(!q.empty()){
		int top = q.front();
		q.pop();
		for(int i=0; i<N[top].next.size(); i++){
			int v=N[top].next[i].end;
			//若第v個城市離s城市有更短的路徑
			//則更改第v個城市到s城市的最短路徑且將v入隊
			if(N[v].min_dis>N[top].min_dis+N[top].next[i].len){
				N[v].min_dis=N[top].min_dis+N[top].next[i].len;
					q.push(v);
			}
		}
	}
}

int main(){
	int n, m, s;
	cin>>n>>m>>s;
	for(int i=1; i<=n; i++){
		N[i].min_dis= (1<<31)-1;
	}
	
	for(int i=0; i<m; i++){
		int u, v, w;
		cin>>u>>v>>w;
		tmp.end=v;
		tmp.len=w;
		N[u].next.push_back(tmp);
	}
	
	N[s].min_dis=0;
	bfs(s);
	
	for(int i=1; i<=n; i++){
		cout<<N[i].min_dis<<" ";
	}
	
	return 0;
}

若文章對你有幫助,可以留個贊麼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章