您的位置:首页 > 其它

最短路 spfa 算法 && 链式前向星存图

2017-11-10 20:26 483 查看
推荐博客 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: