(模板)hdoj2544(最短路--bellman-ford算法&&spfa算法)
题目链接:https://vjudge.net/problem/HDU-2544
题意:给n个点,m条边,求点1到点n的最短路。
思路:
今天学了下bellman_ford,抄抄模板。dijkstra算法和该算法都是单源最短路径算法,但是dij不能适用含负权边的图。而bellman-ford算法适用于负权边,原理是进行n-1次松弛操作,每次都要对m条边进行松弛,所以算法复杂度是O(mn),比dijkstra要高。如果n-1次操作之后还能进行松弛,说明存在负环。
AC code:
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- using namespace std;
- const int maxn=;
- const int maxm=;
- const int inf=0x3f3f3f3f;
- int n,m,dis[maxn],cnt,loop;
- struct node{
- int u,v,w;
- }edge[maxm<<];
- void adde(int u,int v,int w){
- edge[++cnt].v=v;
- edge[cnt].u=u;
- edge[cnt].w=w;
- }
- void bellman_ford(int s){
- for(int i=;i<=n;++i)
- dis[i]=inf;
- dis[s]=;
- //n-1次松弛
- for(int i=;i<n;++i){
- bool ok=;
- for(int j=;j<=cnt;++j){
- int u=edge[j].u,v=edge[j].v,w=edge[j].w;
- if(dis[v]>dis[u]+w){
- dis[v]=dis[u]+w;
- ok=;
- }
- }
- if(!ok) break;
- }
- //loop=1说明存在负环
- for(int i=;i<=cnt;++i){
- int u=edge[i].u,v=edge[i].v,w=edge[i].w;
- if(dis[v]>dis[u]+w){
- loop=;
- break;
- }
- }
- }
- int main(){
- while(scanf("%d%d",&n,&m),n||m){
- cnt=,loop=;
- for(int i=;i<=m;++i){
- int u,v,w;
- scanf("%d%d%d",&u,&v,&w);
- adde(u,v,w);
- adde(v,u,w);
- }
- bellman_ford();
- printf("%d\n",dis[n]);
- }
- return ;
- }
思路2:
spfa是bellman-ford的队列优化版本,使用条件一样,vis标记该点是否在队列中,被更新的结点如果不在队列中要重新入队。也可以用来求是否存在负环,用updcnt数组记录每个结点更新次数,如果==n说明更新了n次,即存在负环。
然后说一下spfa的时间复杂度是O(km),k为常数,但最坏情况是O(mn),比较毒瘤,慎用!
下面的代码是luoguP3385,判负环。
AC code:
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<queue>
- using namespace std;
- const int maxn=;
- const int maxm=;
- const int inf=0x3f3f3f3f;
- int T,n,m,head[maxn],vis[maxn],cnt,upd[maxn],dis[maxn];
- struct node{
- int v,w,nex;
- }edge[maxm];
- void adde(int u,int v,int w){
- edge[++cnt].v=v;
- edge[cnt].w=w;
- edge[cnt].nex=head[u];
- head[u]=cnt;
- }
- bool spfa(){
- for(int i=;i<=n;++i)
- vis[i]=,upd[i]=,dis[i]=inf;
- queue<int> que;
- que.push();
- vis[]=,dis[]=,++upd[];
- while(!que.empty()){
- int u=que.front();que.pop();
- vis[u]=;
- for(int i=head[u];i;i=edge[i].nex){
- int v=edge[i].v,w=edge[i].w;
- if(dis[v]>dis[u]+w){
- dis[v]=dis[u]+w;
- if(!vis[v]){
- ++upd[v];
- if(upd[v]>n) return true;
- vis[v]=;
- que.push(v);
- }
- }
- }
- }
- return false;
- }
- int main(){
- scanf("%d",&T);
- while(T--){
- scanf("%d%d",&n,&m);
- for(int i=;i<=n;++i)
- head[i]=;
- cnt=;
- for(int i=;i<=m;++i){
- int u,v,w;
- scanf("%d%d%d",&u,&v,&w);
- if(w<){
- adde(u,v,w);
- }
- else{
- adde(u,v,w);
- adde(v,u,w);
- }
- }
- if(spfa()) printf("YE5\n");
- else printf("N0\n");
- }
- return ;
- }
拓展:
bellman-ford算法还能用来求最长路或者是判断正环,只用改下松弛条件即可。改变dis数组的定义为从源点到其它结点最长路径的长度,初始化为0,松弛时,如果dis[v]<dis[u]+w,则更新,其它操作一样。入poj1860。
AC code:
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<queue>
- using namespace std;
- const int maxn=;
- int n,m,s,head[maxn],vis[maxn],upd[maxn],cnt;
- double V,dis[maxn];
- struct node{
- int v,nex;
- double r,c;
- }edge[maxn<<];
- void adde(int u,int v,double r,double c){
- edge[++cnt].v=v;
- edge[cnt].r=r;
- edge[cnt].c=c;
- edge[cnt].nex=head[u];
- head[u]=cnt;
- }
- bool spfa(int s,double V){
- for(int i=;i<=n;++i) dis[i]=,vis[i]=,upd[i]=;
- dis[s]=V,vis[s]=;
- queue<int> que;
- que.push(s);
- ++upd[s];
- while(!que.empty()){
- int u=que.front();que.pop();
- vis[u]=;
- for(int i=head[u];i;i=edge[i].nex){
- int v=edge[i].v;
- double r=edge[i].r,c=edge[i].c;
- if(dis[v]<(dis[u]-c)*r){
- dis[v]=(dis[u]-c)*r;
- if(!vis[v]){
- ++upd[v];
- if(upd[v]>n) return true;
- que.push(v);
- vis[v]=;
- }
- }
- }
- }
- if(dis[s]>V) return true;
- return false;
- }
- int main(){
- scanf("%d%d%d%lf",&n,&m,&s,&V);
- for(int i=;i<=n;++i) head[i]=;
- cnt=;
- for(int i=;i<=m;++i){
- int u,v;
- double ruv,cuv,rvu,cvu;
- scanf("%d%d%lf%lf%lf%lf",&u,&v,&ruv,&cuv,&rvu,&cvu);
- adde(u,v,ruv,cuv);
- adde(v,u,rvu,cvu);
- }
- if(spfa(s,V)) printf("YES\n");
- else printf("NO\n");
- return ;
- }
(模板)hdoj2544(最短路--bellman-ford算法&&spfa算法)的更多相关文章
- hdoj2544 最短路(Dijkstra || Floyd || SPFA)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2544 思路 最短路算法模板题,求解使用的Dijkstra算法.Floyd算法.SPFA算法可以当做求解 ...
- 六度分离(floyd算法,SPFA算法,最短路—Dijkstra算法)
Time Limit : 5000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submission(s) ...
- UESTC - 1987 童心未泯的帆宝和乐爷 (第k短路 A*算法+SPFA算法 模板)
传送门: http://www.qscoj.cn/#/problem/show/1987 童心未泯的帆宝和乐爷 Edit Time Limit: 10000 MS Memory Limit: ...
- Bellman-Ford算法与SPFA算法详解
PS:如果您只需要Bellman-Ford/SPFA/判负环模板,请到相应的模板部分 上一篇中简单讲解了用于多源最短路的Floyd算法.本篇要介绍的则是用与单源最短路的Bellman-Ford算法和它 ...
- Bellman-ford算法、SPFA算法求解最短路模板
Bellman-ford 算法适用于含有负权边的最短路求解,复杂度是O( VE ),其原理是依次对每条边进行松弛操作,重复这个操作E-1次后则一定得到最短路,如果还能继续松弛,则有负环.这是因为最长的 ...
- 2018/1/28 每日一学 单源最短路的SPFA算法以及其他三大最短路算法比较总结
刚刚AC的pj普及组第四题就是一种单源最短路. 我们知道当一个图存在负权边时像Dijkstra等算法便无法实现: 而Bellman-Ford算法的复杂度又过高O(V*E),SPFA算法便派上用场了. ...
- (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍
这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: / ...
- 图论——最短路:Floyd,Dijkstra,Bellman-Ford,SPFA算法及最小环问题
一.Floyd算法 用于计算任意两个节点之间的最短路径. 参考了five20的博客 Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个 ...
- [板子]SPFA算法+链式前向星实现最短路及负权最短路
参考:https://blog.csdn.net/xunalove/article/details/70045815 有关SPFA的介绍就掠过了吧,不是很赞同一些博主说是国内某人最先提出来,Bellm ...
随机推荐
- mac系统提示 interactive intelligence 的恼人问题
处理 interacti intelligence 提示问题记录 二手购买了一台电脑,从最初的小白到现在稍微熟悉mac的使用, 一直困扰我的便是一个提示, 上图 困扰多年, 记录一下解决和尝试过程吧. ...
- CSS Sticky 其实很简单
为什么要写这篇文章 Sticky 也不是新知识点了,写这篇文章的原因是由于最近在实现效果的过程中,发现我对 Sticky 的理解有偏差,代码执行结果不如预期.决定写篇文章重新学习一次. 什么是 Sti ...
- ubuntu之路——day11.1 如何进行误差分析
举个例子 还是分类猫图片的例子 假设在dev上测试的时候,有100张图片被误分类了.现在要做的就是手动检查所有被误分类的图片,然后看一下这些图片都是因为什么原因被误分类了. 比如有些可能因为被误分类为 ...
- #C++初学记录(算法测试2019/5/5)(深度搜索)
深度搜索:Oil Deposits GeoSurvComp地质调查公司负责探测地下石油储藏. GeoSurvComp现在在一块矩形区域探测石油,并把这个大区域分成了很多小块.他们通过专业设备,来分析每 ...
- 【转】JVM类装载机制的解析,热更新的探讨
引言 如有错误,请批评指正. Java是一种动态连接的语言.所谓动态连接,大概可以这么解释. 首先,Java可以大概想象成是编译解释执行的.对于一个*.java的文件,通过javac将会编译成一个*. ...
- word: 插入或修改文字时后面的字消失 解决办法
在编辑Word文档中的文字时,我们有时需要插入或修改文字,可是在插入或修改时会发现改动处后面的文字会消失.比如插入或修改3个字,后面的文字随之也会消失3个,这时该怎么办呢? 点击-“文件”-“选项”- ...
- 007 CSS基本选择器
复习. 一:类选择器 1.多类名选择器 使用场景:某个标签上需要多个类进行描述. 多个类之间使用空格分开. 冲突的时候,和类名在html中的先后顺序没有关系,和css中的样式的先后顺序有关系. 2.案 ...
- Objective-C轻量级泛型
在Apple发布Xcode7的时候,不仅把Swift编程语言升级到了2.0版本,而且还对Objective-C做了许多提升,包括引入__nonnull/__nullable.其中,对于Objectiv ...
- 实战二:LoadRunner创建一个测试脚本
问题一:执行脚本浏览器不能自动启动??? 原因:loadrunner11只支持IE9以下浏览器和火狐低版本浏览器 解决办法:1.IE浏览器取消勾选[启用第三方浏览器扩展]启动IE,从[工具]进入[In ...
- 解决IE浏览器没有网络的情况
计算机能够连接到网络,但是IE浏览器却显示没有网络. 解决方案: 设置 >> IE internet选项: 选择“高级”: 选择“重置”: 勾选“删除个人设置”,点击重置: 重新打开IE, ...