题目链接: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算法)的更多相关文章

  1. hdoj2544 最短路(Dijkstra || Floyd || SPFA)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2544 思路 最短路算法模板题,求解使用的Dijkstra算法.Floyd算法.SPFA算法可以当做求解 ...

  2. 六度分离(floyd算法,SPFA算法,最短路—Dijkstra算法)

    Time Limit : 5000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) ...

  3. UESTC - 1987 童心未泯的帆宝和乐爷 (第k短路 A*算法+SPFA算法 模板)

    传送门: http://www.qscoj.cn/#/problem/show/1987 童心未泯的帆宝和乐爷 Edit Time Limit: 10000 MS     Memory Limit: ...

  4. Bellman-Ford算法与SPFA算法详解

    PS:如果您只需要Bellman-Ford/SPFA/判负环模板,请到相应的模板部分 上一篇中简单讲解了用于多源最短路的Floyd算法.本篇要介绍的则是用与单源最短路的Bellman-Ford算法和它 ...

  5. Bellman-ford算法、SPFA算法求解最短路模板

    Bellman-ford 算法适用于含有负权边的最短路求解,复杂度是O( VE ),其原理是依次对每条边进行松弛操作,重复这个操作E-1次后则一定得到最短路,如果还能继续松弛,则有负环.这是因为最长的 ...

  6. 2018/1/28 每日一学 单源最短路的SPFA算法以及其他三大最短路算法比较总结

    刚刚AC的pj普及组第四题就是一种单源最短路. 我们知道当一个图存在负权边时像Dijkstra等算法便无法实现: 而Bellman-Ford算法的复杂度又过高O(V*E),SPFA算法便派上用场了. ...

  7. (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍

    这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: / ...

  8. 图论——最短路:Floyd,Dijkstra,Bellman-Ford,SPFA算法及最小环问题

    一.Floyd算法 用于计算任意两个节点之间的最短路径. 参考了five20的博客 Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个 ...

  9. [板子]SPFA算法+链式前向星实现最短路及负权最短路

    参考:https://blog.csdn.net/xunalove/article/details/70045815 有关SPFA的介绍就掠过了吧,不是很赞同一些博主说是国内某人最先提出来,Bellm ...

随机推荐

  1. PHP var_dump() 函数

    var_dump() 函数用于输出变量的相关信息 <?php $b = 3.1; $c = true; var_dump($b, $c); ?> 输出 float(3.1) bool(tr ...

  2. ubuntu之路——day10.3 train/dev/test的划分、大小和指标更新

     train/dev/test的划分 我们在前面的博文中已经提到了train/dev/test的相关做法.比如不能将dev和test混为一谈.同时要保证数据集的同分布等. 现在在train/dev/t ...

  3. Linux tar: Cannot change ownership to [..]: Permission denied

    tar xzf $INPUT_FOLDER/archive.tar.gz --no-same-owner -C /mnt/test-nas/

  4. 从Windows命令行启动MySQL

    SERVER: 从Windows命令行启动MySQL 可以从命令行手动启动MySQL服务器.可以在任何版本的Windows中实现. 要想从命令行启动mysqld服务器,你应当启动控制台窗口(或“DOS ...

  5. 微信小程序开发者工具详解

    一.微信小程序web开发工具下载地址 1.1 在微信公众平台-小程序里边去下载开发工具下载地址. 1.2 下载后安装一下就可以使用了: 二.创建项目 2.1 微信小程序web开发工具需要扫码登陆,所以 ...

  6. UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 0: invalid continuation byte

    需求:python如何实现普通用户登录服务器后切换到root用户再执行命令 解决参考: 代码: def verification_ssh(host,username,password,port,roo ...

  7. 从内核3.7版本开始,Linux就开始支持VXLAN 到了内核3.12版本,Linux对VXLAN的支持已经完备,支持单播和组播,IPv4和IPv6。

    一.关于VXLAN VXLAN 是 Virtual eXtensible LANs 的缩写,它是对 VLAN 的一个扩展,是非常新的一个 tunnel 技术,在Open vSwitch中应用也非常多. ...

  8. 算力和AI-ZILLIZ

    特征向量检索加速.https://www.zilliz.com/ 公司介绍: MegaWise异构众核加速数据库 MegaWise是ZILLIZ独立自主研发的新一代异构众核加速数据库系统.MegaWi ...

  9. 为Apache添加MP4扩展

    apxs是apache的一个辅助工具软件,它通常用来为apache安装扩展模块,甚至可以直接将.c的源程序自动编译成.so程序,并能自动配置httpd.conf文件,将新安装的扩展添加到配置文件中启用 ...

  10. Netty服务器连接池管理设计思路

    应用场景: 在RPC框架中,使用Netty作为高性能的网络通信框架时,每一次服务调用,都需要与Netty服务端建立连接的话,很容易导致Netty服务器资源耗尽.所以,想到连接池技术,将与同一个Nett ...