图论之最短路算法模板总结

来个大致的分类:

朴素的迪杰斯特拉:

实现:

我们让s表示当前已经确定的最短距离的点,我们找到一个不在s中的距离最近的点t,并用t来更新其他的点。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
//求1---n的最短路(用邻接矩阵存储)
const int N=510;
int n,m;
int g[N][N];
int dis[N];
bool st[N];
int dij()
{memset(dis,0x3f,sizeof(dis));dis[1]=0;for(int i=0;i<n;i++)//一共n次{int t=-1;//找最近的点for(int j=1;j<=n;j++){if(!st[j]&&(t==-1||dis[t]>dis[j])) t=j;}st[t]=1;//更新for(int j=1;j<=n;j++){dis[j]=min(dis[j],dis[t]+g[t][j]);}}if(dis[n]==1e8) return -1;return dis[n];
}
int main()
{cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j) g[i][j]=0;else g[i][j]=1e8;}}while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);g[a][b]=min(g[a][b],c);}cout<<dij();
}

堆优化的迪杰斯特拉:

#include<bits/stdc++.h>
using namespace std;
const int N=100100;
int n,m;
int h[N],w[N],e[N],ne[N],id;
int dis[N];
bool st[N];
typedef pair<int,int> pii;
void add(int a,int b,int c)
{e[id]=b,w[id]=c,ne[id]=h[a],h[a]=id++;
}
int dij()
{memset(dis,0x3f,sizeof(dis));dis[1]=0;priority_queue<pii,vector<pii>,greater<pii>> heap;heap.push({0,1});while(!heap.empty()){auto t=heap.top();heap.pop();int ver=t.second,dist=t.first;if(st[ver]) continue;st[ver]=1;for(int i=h[ver];i!=-1;i=ne[i]){int j=e[i];if(dis[j]>dist+w[i]){dis[j]=dist+w[i];heap.push({dis[j],j});}}}if(dis[n]==0x3f3f3f3f) return -1;return dis[n];
}
int main()
{cin>>n>>m;memset(h,-1,sizeof(h));while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);}cout<<dij();
}

Bellman-Ford算法:

实现:循环n次,每一次循环所有边并更新。

注意:有负权的可能没有最短路,我们最外面循环了k次,他的含义是最多经过k条边的最短路,因此若循环超过该次数说明有环,这样子就是有负环了,但是有负环不一定说明答案不存在比方说一个与答案路径无关的负环,因此一般无法用该算法判断。

下面是AC代码(只可以走k条边):

#include<bits/stdc++.h>
using namespace std;
const int N=510,M=100010;
int n,m,k,f;
int dis[N],backup[N];
struct node
{int a,b,w;}edge[M];
int bel()
{memset(dis,0x3f,sizeof(dis));dis[1]=0;for(int i=0;i<k;i++){memcpy(backup,dis,sizeof(dis));//防止更新时用同一回的更新for(int j=0;j<m;j++){int a=edge[j].a,b=edge[j].b,w=edge[j].w;dis[b]=min(dis[b],backup[a]+w);}}if(dis[n]>0x3f3f3f3f/2){f=1;return -1;} //有负权边return dis[n];
}
int main()
{cin>>n>>m>>k;for(int i=0;i<m;i++){int a,b,w;scanf("%d%d%d",&a,&b,&w);edge[i]={a,b,w};}int t=bel();if(t==-1&&f) cout<<"impossible";else cout<<t;
}

SPFA算法:

#include<bits/stdc++.h>
using namespace std;
const int N=100100;
int n,m;
int h[N],w[N],e[N],ne[N],id;
int dis[N];
bool st[N];
void add(int a,int b,int c)
{e[id]=b,w[id]=c,ne[id]=h[a],h[a]=id++;
}
int spfa()
{   memset(dis,0x3f,sizeof(dis));dis[1]=0;queue<int> q;q.push(1);st[1]=1;while(q.size()){int t=q.front();q.pop();st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(dis[j]>dis[t]+w[i]){dis[j]=dis[t]+w[i];if(!st[j]){q.push(j);st[j]=1;}}}}if(dis[n]==0x3f3f3f3f) return -1;return dis[n];
}
int main()
{cin>>n>>m;memset(h,-1,sizeof(h));while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);}int t=spfa();if(t==-1) cout<<"impossible";else cout<<t;
}

SPFA求负环:

同时维护cnt[x]表示当前最短路的边数,我们cnt[x]=cnt[t]+1,若有cnt[x]>=n,说明有了负环。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=100100;
int n,m;
int h[N],w[N],e[N],ne[N],id;
int dis[N],cnt[N];
bool st[N];
void add(int a,int b,int c)
{e[id]=b,w[id]=c,ne[id]=h[a],h[a]=id++;
}
int spfa()
{   queue<int> q;for(int i=1;i<=n;i++){st[i]=1;q.push(i);}//相当于一个超级源点while(q.size()){int t=q.front();q.pop();st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(dis[j]>dis[t]+w[i]){dis[j]=dis[t]+w[i];cnt[j]=cnt[t]+1;if(cnt[j]>=n) return 1;if(!st[j]){q.push(j);st[j]=1;}}}}return 0;
}
int main()
{cin>>n>>m;memset(h,-1,sizeof(h));while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c);}int t=spfa();if(t==1) cout<<"Yes";else cout<<"No";
}

Floyd算法:

#include<bits/stdc++.h>
using namespace std;
const int N = 210, INF = 1e9;
int n, m, q;
int d[N][N];
void floyd()
{for (int k = 1; k <= n; k ++ )for (int i = 1; i <= n; i ++ )for (int j = 1; j <= n; j ++ )d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}int main()
{scanf("%d%d%d", &n, &m, &q);for (int i = 1; i <= n; i ++ )for (int j = 1; j <= n; j ++ )if (i == j) d[i][j] = 0;else d[i][j] = INF;while (m -- ){int a, b, c;scanf("%d%d%d", &a, &b, &c);d[a][b] = min(d[a][b], c);}floyd();while (q -- ){int a, b;scanf("%d%d", &a, &b);int t = d[a][b];if (t > INF / 2) puts("impossible");else printf("%d\n", t);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/661627.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apache SeaTunnel k8s 集群模式 Zeta 引擎部署指南

SeaTunnel提供了一种运行Zeta引擎(cluster-mode)的方法&#xff0c;可以让Kubernetes在本地运行Zeta引擎&#xff0c;实现更高效的应用程序部署和管理。在本文中&#xff0c;我们将探索SeaTunnel k8s运行zeta引擎(cluster-mode模式)的更多信息&#xff0c;了解如何更好地利用Ze…

从正文开始计算并设置第x页,共x页

如下图&#xff0c;本人正文以下内容只有34页&#xff0c;但wps/word会自动计算全部的页数&#xff0c;看到网上有许多解决方法&#xff0c;但都太麻烦&#xff0c;下面教你两步解决所有问题。 第一步&#xff0c;手动更改第1页的共x页的x为自己需要的页数。 第二步&#xff0c…

【JavaWeb Day 2 - JS 】

JavaWeb Day 2 - JS JS背景故事1. JS 引入方式2. JS 基本语法2.2 变量2.3 数据类型2.4 运算符 3. JS 函数4. JS 对象4.1 Array对象4.2 String对象4.3 JSON对象4.4 BOM对象4.4.1 windows 对象4.4.2 location 对象 4.5 DOM 对象DOM 案例 5. JS 事件监听5.1 JS 事件绑定 及 常见事…

PF-NET与3D点云补全

文章目录 点云补全 (Point Cloud Completion) 点云补全 (Point Cloud Completion) 3D点云补全问题的主要目标是估计缺失点 点云坐标。这个问题在实际解决的时候主要有2个问题&#xff0c;第一就是点云补充得过于完整&#xff0c;比如目标点云中是有缺口&#xff0c;但是补全的…

人脸识别概念解析

目录 1. 概述 2. 人脸检测 3. 人脸跟踪 4. 质量评价 5. 活体检测 6. 特征提取 7. 人脸验证 8. 人脸辨识 1. 概述 人脸识别在我们的生活中随处可见&#xff0c;例如在大楼门禁系统中&#xff0c;它取代了传统的门禁卡或密码&#xff0c;提高了进出的便捷性和安全性。在商…

Edge浏览器新特性深度解析,写作ai免费软件

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

Protobuf 通信协议

Protobuf Protobuf 简介使用技术内幕 Protobuf 简介 在移动互联网时代&#xff0c;手机流量、电量是最为有限的资源&#xff0c;而移动端的即时通讯应用无疑必须得直面这两点 解决流量过大的基本方法就是使用高度压缩的通信协议&#xff0c;而数据压缩后流量减小带来的自然结…

暴雨服务器引领信创算力新潮流

去年大模型的空前发展&#xff0c;人工智能也终于迎来了属于自己的“文艺复兴”&#xff0c;众多的模型相继发布&#xff0c;继而催生了整个行业对于智能算力需求的激增。 市场需求与技术驱动仿佛现实世界的左右脚&#xff0c;催动着世界文明的齿轮向前滚动。在全球经济角逐日…

Android创建快捷方式到桌面

效果图 参考 https://blog.51cto.com/u_16175498/8811197https://blog.51cto.com/u_16175498/8811197 权限 <uses-permission android:name"com.android.launcher.permission.INSTALL_SHORTCUT" /> 实现 if (Build.VERSION.SDK_INT > Build.VERSION_C…

【Java】实现一个简单的线程池

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 ​编辑 一、线程池的模式 二、线程池的一些参数 三、代码实现 1.BlockingQueue 2.ThreadPool 四、拒绝策略 一、线程池的模式 线程池顾名思义就是管理线程的一个池子&#xff0c;我们把创建线程的过程交给…

Murphy:优维大模型运维数智人上线服役

01 墨菲定律&#xff1a; 幽默又严肃的NASA军规 「墨菲定律」 &#xff08;Murphy’s law&#xff09; 任何可能出错的事情最终都会出错 墨菲定律强调了在复杂系统和人类活动中&#xff0c;事情往往会出现意想不到的差错。虽然这只是一种对人类经验和偶然性的幽默概括与启…

iA Writer for Mac:简洁强大的写作软件

在追求高效写作的今天&#xff0c;iA Writer for Mac凭借其简洁而强大的功能&#xff0c;成为了许多作家、记者和学生的首选工具。这款专为Mac用户打造的写作软件&#xff0c;以其独特的设计理念和实用功能&#xff0c;助你轻松打造高质量的文章。 iA Writer for Mac v7.1.2中文…