1. 程式人生 > >最短路 spfa 算法 && 鏈式前向星存圖

最短路 spfa 算法 && 鏈式前向星存圖

.com mem ont .aspx 百度 dfs edit 時間復雜度 tails

推薦博客 https://i.cnblogs.com/EditPosts.aspx?opt=1

     http://blog.csdn.net/mcdonnell_douglas/article/details/54379641

spfa 自行百度 說的很詳細

spfa 有很多實現的方法 dfs 隊列 棧 都可以 時間復雜度也不穩定 不過一般情況下要比bellman快得多

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include 
<sstream> #include <algorithm> #include <string> #include <queue> #include <ctime> #include <vector> using namespace std; const int maxn= 1e3+5; const int maxm= 1e3+5; const int inf = 0x3f3f3f3f; typedef long long ll; int n,m,s; //n m s 分別表示 點數-標號從1開始 邊數-標號從0開始 起點 struct
edge { int to,w; }; int d[maxn]; //d[i]表示 i 點到源點 s 的最短距離 int p[maxn]; //p[i]記錄最短路到達 i 之前的節點 int visit[maxn]; // 標記是否已進隊 int cnt[maxn]; vector<edge> v[maxn]; int spfa(int x) { queue<int> q; memset(visit,0,sizeof(visit)); memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++) d[i]
=inf; d[x]=0; visit[x]=1; q.push(x); while(!q.empty()) { int u=q.front();q.pop(); visit[u]=0; for(int i=0;i<v[u].size();i++) { edge &e=v[u][i]; if(d[u]<inf&&d[u]+e.w<d[e.to]) { d[e.to]=d[u]+e.w; p[e.to]=u; if(!visit[e.to]) { q.push(e.to); visit[e.to]=1; if(++cnt[e.to]>n) return 0; } } } } return 1; } void Print_Path(int x) { while(x!=p[x]) //逆序輸出 正序的話用棧處理一下就好了 { printf("%d ",x); x=p[x]; } printf("%d\n",x); } int main() { while(scanf("%d %d %d",&n,&m,&s)!=EOF) { int x,y,z; for(int i=0;i<m;i++) { scanf("%d %d %d",&x,&y,&z); edge e; e.to=y; e.w=z; v[x].push_back(e); // e.to=x; //無向圖 反向建邊 // v[y].push_back(e); } p[s]=s; if(spfa(s)==1) for(int i=1;i<=n;i++) { printf("%d %d\n",i,d[i]); Print_Path(i); } else printf("sorry\n"); return 0; } }

鏈式前向星存圖

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 #include <stdlib.h>
 5 #include <iostream>
 6 #include <sstream>
 7 #include <algorithm>
 8 #include <string>
 9 #include <queue>
10 #include <ctime>
11 #include <vector>
12 using namespace std;
13 const int maxn= 1e3+5;
14 const int maxm= 1e3+5;
15 const int inf = 0x3f3f3f3f;
16 typedef long long ll;
17 int n,m;
18 int first[maxn];
19 struct edge
20 {
21     int to,next,w;
22 }e[maxn];
23 void add(int i,int u,int v,int w)
24 {
25     e[i].to=v;
26     e[i].w=w;
27     e[i].next=first[u];
28     first[u]=i;
29 }
30 int main()
31 {
32     scanf("%d %d",&n,&m);
33     {
34         int u,v,w;
35         memset(first,-1,sizeof(first));
36         for(int i=0;i<m;i++)
37         {
38             scanf("%d %d %d",&u,&v,&w);
39             add(i,u,v,w);
40         }
41         for(int i=1;i<=n;i++)
42         {
43              cout<<"from"<<i<<endl;
44              for(int j=first[i];j!=-1;j=e[j].next)  //遍歷以j為起點的每條邊
45                 cout<<"to"<<e[j].to<<" length="<<e[j].w<<endl;
46         }
47 
48     }
49 }
50 //輸入
51 //6 9
52 //1 2 2
53 //1 4 -1
54 //1 3 1
55 //3 4 2
56 //4 2 1
57 //3 6 3
58 //4 6 3
59 //6 5 1
60 //2 5 -1
61 //輸出
62 //from1
63 //to3 length=1
64 //to4 length=-1
65 //to2 length=2
66 //from2
67 //to5 length=-1
68 //from3
69 //to6 length=3
70 //to4 length=2
71 //from4
72 //to6 length=3
73 //to2 length=1
74 //from5
75 //from6
76 //to5 length=1

最短路 spfa 算法 && 鏈式前向星存圖