最短路-- 迪杰斯特拉dij

前置知识

1. 链式前向星 (存图)

const int N=1e5+10;
int head[N];

typedef struct
{
    int qi,to,val;
    int pre;
}stu ;
stu p[N];

void add(int u,int v,int w)
{
    p[++cnt].qi=u;
    p[cnt].to=v;
    p[cnt].val=w;
    p[cnt].pre=head[u];
    head[u]=cnt;
}



2.优先队列

/*第一种*/
typedef long long ll;

 priority_queue< pair<ll,ll> >q;



/*第二种  自定义优先队列排序方式*/ 

struct cmp      //  优化, 使 路径长度  按从小到大排序
{
    int v,d;     // (距离 ,点)
    bool operator <(const cmp &b)const
    {
        return v>b.v;
    }

};
priority_queue<cmp>q;

3.迪杰斯特拉 最短路模板

// 模板一
struct cmp      //  优化, 使 路径长度  按从小到大排序
{
    int v,d;
    bool operator <(cosnst cmp &b)const
    {
        return v>b.v;
    }

};
void dij(int s,ll dis[])
{

  priority_queue<cmp>q;
    dis[s]=0;   // 源点 为s
   q.push({0,s});

   struct cmp k;
   while(!q.empty())
   {
      k=q.top();
      q.pop();
      
     int u=k.d;
      if(k.v>dis[u])   // 小优化,不是数据超大的情况可以不用
      {
          continue;
      }

      for(int i=head[u];i!=-1;i=p[i].pre)
      {  
          int v=p[i].to;
          if(dis[v]>dis[u]+p[i].val)
          {
              dis[v]=dis[u]+p[i].val;
              q.push({dis[v],v});
          }
      }
   }

}

/*模板二  (个人感觉比较上面的自定义优先队列  速度快 )*/
void dij(int s,ll dis[])
{
    priority_queue< pair<ll,ll> >q;
    while(!q.empty())
        q.pop();

    dis[s]=0;
    q.push(make_pair(0,s));
   pair<ll,ll>  k;
    while(!q.empty())
    {
       k=q.top();
       q.pop();
       int u=k.second;

       if(fabs(k.first)>dis[u])   // 小优化,不是数据超大的情况可以不用
         continue;

        for(int i=head[u];i!=-1;i=p[i].pre)
        {
            int v=p[i].to;
            if(dis[v]>dis[u]+p[i].val)
            {
                dis[v]=dis[u]+p[i].val;
                q.push(make_pair(-dis[v],v));
            }
        }
    }

}

4.完整代码

洛谷 最短路 模板题

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
const long long  inf=0x3f3f3f3f3f3f3f3f;
int n,m,cnt;
int head[N];
ll dis[N];
typedef struct
{
    int qi,to,val;
    int pre;

}stu ;
stu p[N];
void add(int u,int v,int w)
{
    p[++cnt].qi=u;
    p[cnt].to=v;
    p[cnt].val=w;
    p[cnt].pre=head[u];
    head[u]=cnt;
}

/*void dij(int s,ll dis[])
{
    priority_queue< pair<ll,ll> >q;
    while(!q.empty())
        q.pop();

    dis[s]=0;
    q.push(make_pair(0,s));
   pair<ll,ll>  k;
    while(!q.empty())
    {
       k=q.top();
       q.pop();
       int u=k.second;

       if(k.first>dis[u])
         continue;

        for(int i=head[u];i!=-1;i=p[i].pre)
        {
            int v=p[i].to;
            if(dis[v]>dis[u]+p[i].val)
            {
                dis[v]=dis[u]+p[i].val;
                q.push(make_pair(-dis[v],v));
            }
        }
    }

}*/


struct cmp      //  优化, 使 路径长度  按从小到大排序
{
    int v,d;
    bool operator <(const cmp &b)const
    {
        return v>b.v;
    }

};
void dij(int s,ll dis[])
{


priority_queue<cmp>q;

   dis[s]=0;   // 源点 为s
   q.push({0,s});

   struct cmp k;
   while(!q.empty())
   {
      k=q.top();
      q.pop();
      
     int u=k.d;
      if(k.v>dis[u])
      {
          continue;
      }

      for(int i=head[u];i!=-1;i=p[i].pre)
      {  
          int v=p[i].to;
          if(dis[v]>dis[u]+p[i].val)
          {
              dis[v]=dis[u]+p[i].val;
              q.push({dis[v],v});
          }
      }
   }

}

void init()
{
    cnt=-1;
    for(int i=1;i<=n;i++)
    {
        head[i]=-1;
        dis[i]=inf;
    }
}


int main()
{
    int x,y,z;
    int s;
    scanf("%d %d %d",&n,&m,&s);

    init();   //初始化  

    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        add(x,y,z);
    }

    dij1(s,dis);

    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        if(i!=n)
        printf("%lld ",dis[i]);
        else
        printf("%lld\n",dis[i]);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/nefu__lian/article/details/107564670
今日推荐