最短路 spfa 算法 && 链式前向星存图
Posted 灬从此以后灬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最短路 spfa 算法 && 链式前向星存图相关的知识,希望对你有一定的参考价值。
推荐博客 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 算法 && 链式前向星存图的主要内容,如果未能解决你的问题,请参考以下文章
CSU 1333 & Uva 12661 Funny Car Racing最短路变形+spfa算法,链式前向星建图
luogu P3371 & P4779 ---单源最短路径spfa & 最大堆优化Dijkstra
It's not a Bug, It's a Feature! (poj 1482 最短路SPFA+隐式图+位运算)