图论-单源最短路-SPFA算法
有关概念:
最短路问题:若在图中的每一条边都有对应的权值,求从一点到另一点之间权值和最小的路径
SPFA算法的功能是求固定起点到图中其余各点的的最短路(单源最短路径)
约定:图中不存在负权环,用邻接表存储有向图,di存放从起点到结点i的最短路,q为队列,保存待处理节点
思路:
首先指定起点入队,取当前队头结点u,沿每一条与u相连的边向外扩展,对该边所指向的结点v松弛(比较当前dv与当前du加此边长,更新最短路值dv,以及最短路径prev)如果v不在队列中且更新了最短路值,v进队,直至队列中没有元素时终止
较于Dijkstra,SPFA能处理带负权的边,但如果点进队的次数过多,时间效率就不如前者高
#include<cstdio>
#include<cstring>
#define MAXN
#define MAXM
#define INF 214748364
int n,m,cnt,d[MAXN],heads[MAXN],q[MAXN],pre[MAXN];
int head,tail;//队头、队尾指针
bool viss[MAXN];//结点i是否在队列中
struct node
{
int u,v;
int next;
int val;
}edge[MAXM];
void add(int x,int y,int z)
{
edge[++cnt].u=x;
edge[cnt].v=y;
edge[cnt].next=heads[x];
edge[cnt].val=z;
heads[x]=cnt;
}
void SPFA()
{
head=;tail=;
q[]=;
viss[]=;//默认1为起点
while(head<tail)
{
for(int i=heads[q[head]];i!=;i=edge[i].next)
{
if(d[q[head]]+edge[i].val<d[edge[i].v])
{
d[edge[i].v]=d[q[head]]+edge[i].val;//松弛
pre[edge[i].v]=i;//记录最短路径,pre存储边的序号
if(!viss[edge[i].v])//如果v不在队列中,入队
{
q[tail++]=edge[i].v;
viss[edge[i].v]=true;
}
}
}
viss[q[head]]=false;
head++;//队头出队
}
}
void print(int x)
{
if(edge[x].u==)
{
printf("%d %d ",,edge[x].v);
return ;
}
print(pre[edge[x].u]);
printf("%d ",edge[x].v);
}
int main()
{
scanf("%d%d",&n,&m);
memset(heads,,sizeof(heads));
for(int i=;i<=n;i++)d[i]=INF;
int x,y,z;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);//默认输入双向边,所以存储两条方向相反的边
}
SPFA();
printf("%d\n",d[n]);
x=pre[n];
print(x);//输出路径
return ;
}
图论-单源最短路-SPFA算法的更多相关文章
- 单源最短路——SPFA算法(Bellman-Ford算法队列优化)
spfa的算法思想(动态逼近法): 设立一个先进先出的队列q用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路 ...
- 单源最短路SPFA算法
$huaji^{233……}$模板:洛谷 P3371 #include<iostream> #include<algorithm> #include<cstdio> ...
- 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)
关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...
- 单源最短路——Bellman-Ford算法
1.Dijkstra的局限性 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 列如以 ...
- 单源最短路——dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...
- 单源最短路 Bellman-Ford算法(有向图)
// 单源最短路问题 // Bellman-Ford算法 // 复杂度O(V*E) //! 可以判断负圈 #include <cstdio> #include <iostream&g ...
- 单源最短路dijkstra算法&&优化史
一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结 最朴素算法: 邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+ML ...
- 单源最短路Dijkstra算法——matlab实现
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijk ...
- 单源最短路(Dijkstra算法)
#返回上一级 @Author: 张海拔 @Update: 2015-03-11 @Link: http://www.cnblogs.com/zhanghaiba/p/3514570.html Dijk ...
随机推荐
- [洛谷P3261][JLOI2015]城池攻占
题目大意:有$n$个点的树,第$i$个节点有一个权值$h_i$,$m$个骑士,第$i$个骑士攻击力为$v_i$,一个骑士可以把从它开始的连续的父亲中比它小的节点攻破,攻破一个节点可以把攻击力加或乘一个 ...
- BZOJ2668:[CQOI2012]交换棋子——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2668 https://www.luogu.org/problemnew/show/P3159#sub ...
- [Leetcode] permutations ii 全排列
Given a collection of numbers that might contain duplicates, return all possible unique permutations ...
- HDOJ(HDU).2159 FATE (DP 带个数限制的完全背包)
HDOJ(HDU).2159 FATE (DP 带个数限制的完全背包) 题意分析 与普通的完全背包大同小异,区别就在于多了一个个数限制,那么在普通的完全背包的基础上,增加一维,表示个数.同时for循环 ...
- ACE_Message_Block功能简介
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/30/607960.html ACE_Message_Block在Ace中用来表示消息的存放空间 ...
- Bazinga 字符串HASH 这题不能裸HASH 要优化 毒瘤题
Ladies and gentlemen, please sit up straight. Don't tilt your head. I'm serious. For nn given string ...
- Eclipse集成Android NDK及导出Jar和so动态库
一.安装Cygwin 在Windows环境而又不想使用linux环境,可以安装cygwin(http://www.cygwin.com/ ),为了使用gcc注意cygwin的必选安装包在devel目录 ...
- rank() within group用法【转】
参考:http://www.itpub.net/thread-241824-1-1.html http://blog.itpub.net/13379967/viewspace-481811/ ) w ...
- [技巧篇]21.Android Studio的快捷键设置[图片版]
如果对你有帮助,请点击推荐!
- 小米路由器设置DMZ主机 并在外网访问
一.前提条件: 1.小米路由器 2.拥有公网IP的网络 二.步骤: 1.登陆小米路由器管理界面 miwifi.com 2.高级设置=>端口转发 页面底部的DMZ选项开启,然后选择需要映射到外 ...