最短路优化(优先队列)
前置知识
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;
}