最短路 SPFA()链式前向星

  在极端情况下,图特别大,用邻接链表也会超空间限制,此时需要用到链式前向星来存图。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
 4 const int inf = INT_MAX / 10;
 5 const int num = ???;
 6 struct Edge{
 7     int to, next, w;//edge[i]的i就是起点,终点to,权值w,相同起点的下一条边next
 8 }edge[num];
 9 int n, m, cnt;
10 int head[num];//head[i]存放以i为起点的下一条边
11 int dis[num];
12 int inq[num];//标记节点是否在队列中
13 int neg[num];//判负圈
14 int pre[num];//记录前驱节点
15
16 void print_path(int s, int t){
17     if(s==t)    {printf("%d",s);    return ;}
18     print_path(s, pre[t]);
19     printf("->%d",t);
20 }
21
22 //初始化
23 void init(){
24     for(int i=0; i<num; ++i){
25         edge[i].next = -1;
26         head[i] = -1;
27     }
28     cnt = 0;
29 }
30
31 //加边
32 void addedge(int u, int v, int w){
33     edge[cnt].to = v;
34     edge[cnt].w  = w;
35     edge[cnt].next = head[u];//指向上一条同起点的边
36     head[u] = cnt;//存放以u为起点的某条边edge的下标
37     cnt++;
38 }
39
40 int spfa(int s){
41     for(int i=1; i<=n; ++i){
42         neg[i] = 0;
43         dis[i] = inf;
44         inq[i] = false;
45     }
46     neg[s] = 1;
47     dis[s] = 0;
48
49     queue<int>q;
50     q.push(s);
51     inq[s] = true;
52
53     while(!q.empty()){
54         int u = q.front();
55         q.pop();
56         inq[u] = false;
57
58         for(int i=head[u]; ~i; i=edge[i].next){//~1 即 i!=-1
59             int v = edge[i].to;
60             int w = edge[i].w;
61             if(dis[u] + w < dis[v]){
62                 dis[v] = dis[u] + w;
63                 pre[v] = u;
64                 if(!inq[v]){
65                     inq[v] = true;
66                     q.push(v);
67                     neg[v]++;
68                     if(neg[v] > n) return 1;//v的更新次数超过节点个数n,即说明存在负圈
69                 }
70             }
71         }
72     }
73     //print_path(s,?);
74     return 0;
75 }
76
77 int main(){
78     while(~scanf("%d %d", &n, &m) && n && m){
79         //初始化
80         init();
81         //
82         while(m--){
83             int a, b, c;
84             scanf("%d %d %d", &a, &b, &c);
85             addedge(a, b, c);
86             addedge(b, a, c);
87         }
88         //
89         spfa(1);
90     }
91     return 0;
92 }

  相较原版的spfa(),结构体Edge中多了一个数据类型 next,用于存放同起点的上一条边,这也是省空间的关键所在;同时需要用到的即 head[i],用于存放以 i 为起点的某边的 edge的下标。

原文地址:https://www.cnblogs.com/0424lrn/p/12244146.html

时间: 2024-10-13 08:29:38

最短路 SPFA()链式前向星的相关文章

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

POJ 3159 Candies(差分约束+spfa+链式前向星)

题目链接:http://poj.org/problem?id=3159 题目大意:给n个人派糖果,给出m组数据,每组数据包含A,B,C三个数,意思是A的糖果数比B少的个数不多于C,即B的糖果数 - A的糖果数<=C . 最后求n 比 1 最多多多少颗糖果. 解题思路:经典差分约束的题目,具体证明看这里<数与图的完美结合——浅析差分约束系统>. 不妨将糖果数当作距离,把相差的最大糖果数看成有向边AB的权值,我们得到 dis[B]-dis[A]<=w(A,B).看到这里,我们可以联想到

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

推荐博客  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 <st

单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 设road[i][j]表示相邻的i到j的路长U集合存储已经求得的到源点最短路径的节点,S集合表示还没求得的节点dis[i]表示i到源节点(设为0)的最短路径vis[i]=1表示i节点在U集合中 刚开始dis[0]=0,vis[0]=1;dis[i]=maxn,vis[i]=0;for 1 to

【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)

Dijkstra+ 链式前向星+ 优先队列   Dijkstra算法 Dijkstra最短路算法,个人理解其本质就是一种广度优先搜索.先将所有点的最短距离Dis[ ]都刷新成∞(涂成黑色),然后从起点x (Dis[x]= 0, Dis[]值最小 )开始查询:先将x 加入(涂成灰色),对x 的所有边进行遍历,对所有搜索到的点x+ 1 进行松弛(刷新),若经过x 点的松弛,得到的距离小于原来的值:Dis[x]+ dis(x, x+ 1) < Dis[x+ 1], 则用新值刷新,把x+ 1加入(涂成灰

poj-1459-最大流dinic+链式前向星

title: poj-1459-最大流dinic+链式前向星 date: 2018-11-22 20:57:54 tags: acm 刷题 categories: ACM-网络流-最大流 概述 这道是一道网络流里最大流的板子题,,, 暑期集训网络流草草水过,,连基本的算法都不知道有哪些,,,更别提怎么实现了,,,只知道网络流的大致的概念,, 今天花了一天的时间重新学习了一波,,,本以为这东西很简单,,,没想到不仅算法的实现一大堆的东西,,就连题目都有时候看不懂,,,,感受就是网络流的题不仅算法实

链式前向星

重要的事情说三遍 明天不学会链式前向星我绝食三天

图的存储结构:邻接矩阵(邻接表)&amp;链式前向星

[概念]疏松图&稠密图: 疏松图指,点连接的边不多的图,反之(点连接的边多)则为稠密图. Tips:邻接矩阵与邻接表相比,疏松图多用邻接表,稠密图多用邻接矩阵. 邻接矩阵: 开一个二维数组graph[ ][ ]来记录图中点a与点b之间是否连通,初始化为0(或者-1之类的看情况):如果图中有可忽略的重边(如 只需重边中的最小边或最大边),则保存需要的那条边的边权,但如果有无法忽略的重边,就一定不要用邻接矩阵. int graph[MAXN][MAXN]; void graphInit() { me

HDU3342 Legal or Not【拓扑排序】【链式前向星】

Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4633    Accepted Submission(s): 2115 Problem Description ACM-DIY is a large QQ group where many excellent acmers get together. It is