最短路模板

1.dijkstra算法:

从一点开始,更新所能到达的点的最小值,不能判断有负权值的图

模板:(与Prime算法基本相同)

复制代码
void dij(){//堆优化模板
  priority_queue<pll,vector<pll>,greater<pll>> q;
  memset(dis,0x3f,sizeof(dis));
  memset(vis,0,sizeof(vis));
  q.push({0,1});
  dis[1]=0;
  while(!q.empty()){
    ll u=q.top().first;ll v=q.top().second;
    q.pop();
    if(vis[v]) continue;
    vis[v]=1;
    for(int i=head[v];i;i=e[i].next){
      ll t=e[i].to;
      if(dis[t]>u+e[i].w){
        dis[t]=u+e[i].w;q.push({dis[t],t});
      }
    }
  }
}
复制代码

2.bellman-ford算法:

就是一种遍历,每条边都要跑n次,最后再判断能不能继续松弛,能得话,说明有负权值边。

模板:

复制代码
ll bellman(){
  memset(dis,0x3f,sizeof(dis));
  dis[1]=0;
  for(int i=1;i<=n;i++){
    for(int j=1;j<=cnt;j++){
      if(dis[e[j].y]>dis[e[j].x]+e[j].w){
        dis[e[j].y]=dis[e[j].x]+e[j].w;
      }
    }
  }
  for(int i=1;i<=cnt;i++){//继续松弛,判断有无负边
    if(dis[e[i].y]>dis[e[i].x]+e[i].w) return 1;
  }
  return 0;
}
复制代码

3 spfa算法:

是bellman_ford的优化版本,bellman_ford算法中,当某些点已经找到最短路时,就不需要再遍历松弛,就可以省掉这一部分,保证每次都松弛没有找到最短路的点。

判断是否有负权值,有负权值,就可以无限松弛,正常情况下一个图点数为n,它的松弛次数应为n-1,所以当  n(松弛次数)>=n-1时就证明有负权值

模板:

复制代码
void spfa()
  memset(dis,0x3f,sizeof(dis));
  memset(vis,0,sizeof(vis));
  dis[1]=0;
  queue<ll> q;
  q.push(1);
  vis[1]=1;
  while(!q.empty()){
    ll t=q.front();
    q.pop();
    vis[t]=0;
    for(ll i=head[t];i;i=e[i].next){
      ll j=e[i].to;
      if(dis[j]>dis[t]+e[i].w){
        dis[j]=dis[t]+e[i].w;
        if(!vis[1]){
          q.push(j);vis[j]=1;
        }
      }
    }
  }
}
复制代码

spfa判断负环时:

复制代码
ll spfa(){
  memset(dis,0x3f,sizeof(dis));
  memset(vis,0,sizeof(vis));
  memset(num,0,sizeof(num));
  dis[1]=0;
  queue<ll> q;
  for(ll i=1;i<=n;i++){
    q.push(i);vis[i]=1;
  }//将所有点一次性存入和单独将1存入都可以,前者快些
  while(!q.empty()){
    ll t=q.front();
    q.pop();
    vis[t]=0;
    for(ll i=head[t];i;i=e[i].next){
      ll j=e[i].to;
      if(dis[j]>dis[t]+e[i].w){
        num[j]=num[t]+1;
        if(num[j]>=n) return 1;//判断松弛次数是否>=n
        dis[j]=dis[t]+e[i].w;
        if(!vis[j]){
          q.push(j);vis[j]=1;
        }
      }
    }
  }
  return 0;
}
复制代码

 4.floyd算法

 floyd算法就是利用动态规划的思想进行更新。

利用邻接矩阵储存,其中dis[a][b]表示a->b的最短距离,其中dis[a][a]为0.

模板:

for(ll k=1;k<=n;k++)//更新最短路
    for(ll i=1;i<=n;i++)
      for(ll j=1;j<=n;j++){
         dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
      }

 

posted @   HHzp  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示