dijstra——强大的算法
dijstra+链式前向星+优先队列优化=满分的最短路
由于SPFA在最坏情况下会退化,所以我决定使用dijstra来解决最短路问题。
链式前向星就是存图用的,比邻接矩阵节省空间得多(点这)
而由于dijstra是基于贪心的,所以也可以用优先队列来维护
写个模板吧:
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int inf=1e9,maxn=100005;
int n,m,s,v[maxn],d[maxn],num,head[maxn];
priority_queue< pair<int ,int> >q;//优先队列(成对记录,分别为出发点到i点的距离与i的标号)
struct node{
int next,w,to;
}edge[500005];
void add_edge(int x,int y,int z){//链式前向星建图
num++;
edge[num].to=y;
edge[num].w=z;
edge[num].next=head[x];
head[x]=num;
}
void dijstra(int start){
d[start]=0;
q.push(make_pair(0,start));
while(!q.empty()){
int x=q.top().second;
q.pop();
if(v[x])
continue;
v[x]=1;
for(int i=head[x];i;i=edge[i].next){
int y=edge[i].to,z=edge[i].w;
if(d[y]>d[x]+z){
d[y]=d[x]+z;
q.push(make_pair(-d[y],y));//大根堆变小根堆,原本按从大到小排序,加负号等价于绝对值从小到大排序
}
}
}
}
int main(){
cin>>n>>m>>s;
FOR(i,1,m){
int x,y,z;
cin>>x>>y>>z;
add_edge(x,y,z);
}
FOR(i,1,n){
d[i]=inf;
}
dijstra(s);
FOR(i,1,n){
cout<<d[i]<<" ";
}
return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~