1. 程式人生 > >[Algotithm] 最短路之旅

[Algotithm] 最短路之旅

cnblogs blog cor 16px fine 又是 alt cst names

這可能是非常久以前的東西。

不過想想復習一下也是好的(其實是發現居然不會dijkstra了)。

一、通用原理

維護一個數組記錄所有點的最短路。

枚舉邊確認是否可以通過這條邊減小其它點的最短距離。

得出答案。

二、主流算法

  A. Dijkstra

    Dijkstra,荷蘭人。

    Dijkstra要求提供兩個點集,分別用於存放不再修改的點與待修改的點(也就是是否找到最短路)

    顯然第一個不再修改的點是起點,且其最短路為0。

    那麽,首先找到已知的最短路徑最短的點(想象一個凸多邊形,哪裏離中心最近就哪裏進行擴張)。

    然後這個點扔進不再修改的點集(記為A)。

    然後枚舉其邊以更新其它點的最短路。

    顯然,這種方式將持續n次,因為每次都必然扔且只扔一個點進去點集A。

    然後查找的過程又是n次。

    最後枚舉邊如果用鄰接矩陣的話也是n次,如果用鄰接表的話可以E(E是邊數)。

    PS:我並不是說準確次數啊,n-1 接近 n 所以我直接說 n QwQ

    那麽樸素dijkstra的復雜度就是O(n^2+nE),近似看作O(n^2)。

    

    堆優化:

      想要減小時間復雜度,第一個要優化的就是查找枚舉基點的過程,畢竟每次都O(n)。

      這段部分就其根本是要找到可修改的最短距離。

      那麽我們可以用一個堆(或優先隊列)代替原來的樸素隊列使得我們要找的最小dis每次就在堆頂。

      

    題目:

      單源最短路:https://www.luogu.org/problem/show?pid=3371

      這道題數據還算不錯。

      註意:數據大小需要註意。

技術分享
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 #define maxn_P 10101
 5 #define maxn_E 505050
 6 #define
INF 2147483647 7 using namespace std; 8 typedef pair<int,int> node; 9 10 struct edge{ 11 int from,v,len; 12 }e[maxn_E]; 13 14 int first[maxn_P],tot,dis[maxn_P],n,m,s,a,b,c; 15 bool book[maxn_P]; 16 17 void insert(int u,int v,int len){ 18 tot++; 19 e[tot].from = first[u]; 20 e[tot].v = v; 21 e[tot].len = len; 22 first[u] = tot; 23 } 24 25 void dijkstra(){ 26 for(int i = 1;i <= n;i++) dis[i] = INF; 27 28 priority_queue<node,vector<node>,greater<node> > q; 29 30 dis[s] = 0; 31 32 q.push(make_pair(dis[s],s)); 33 34 while(!q.empty()){ 35 node tmp = q.top(); 36 q.pop(); 37 int p = tmp.second; 38 39 if(!book[p]){ 40 book[p] = true; 41 for(int i = first[p];i;i = e[i].from){ 42 if(dis[e[i].v] > dis[p]+e[i].len){ 43 dis[e[i].v] = dis[p]+e[i].len; 44 q.push(make_pair(dis[e[i].v],e[i].v)); 45 } 46 } 47 } 48 } 49 } 50 51 int main(){ 52 scanf("%d%d%d",&n,&m,&s); 53 54 for(int i = 0;i < m;i++){ 55 scanf("%d%d%d",&a,&b,&c); 56 insert(a,b,c); 57 } 58 59 dijkstra(); 60 61 for(int i = 1;i <= n;i++){ 62 printf("%d ",dis[i]); 63 } 64 65 return 0; 66 }
推薦不看

        

To be filled

[Algotithm] 最短路之旅