时间复杂度:O((n+m)logm)
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
#define MP make_pair
const int N=100010,M=200010;
const int inf=0x7fffffff;
int fr[N],nex[N],dis[N];//邻接表结点数组和距离数组,dis[i]表示源点到i点距离。
int v[M],w[M];//顶点数组和边长数组
bool vis[N];//标记数组
int n,m,s,cnt=0;
priority_queue< pair<int,int> >q;//默认大根堆,第一维为距离的相反值,第二维为顶点编号,利用相反值变成小根堆
void AddEdge(int x,int y,int z)//邻接表存图
{
v[++cnt]=y;
w[cnt]=z;
nex[cnt]=fr[x];
fr[x]=cnt;
}
void Dijkstra()
{
memset(dis,inf,sizeof(dis));//初始化距离为最大
memset(vis,false,sizeof(vis));//清空标记数组
dis[s]=0;
q.push(MP(0,s));//源点入队
while(!q.empty()){
int x=q.top().second;//获取队首编号
q.pop();//队首出队
if(vis[x]) continue;//已处理,continue;
vis[x]=true;
for(int i=fr[x];i;i=nex[i]){//扫描x的所有出边
int y=v[i],z=w[i];
if(dis[y]>dis[x]+z){
dis[y]=dis[x]+z;//松弛
q.push(MP(-dis[y],y));
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m>>s;
for(int i=1;i<=m;i++){
int x,y,z;
cin>>x>>y>>z;
AddEdge(x,y,z);
}
Dijkstra();
for(int i=1;i<=n;i++) cout<<dis[i]<<' ';
return 0;
}
参考于《信息学奥赛一本通--提高篇》