第一次写blog,写的不好请见谅……
链式前向星储存有向图模拟:
模板:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int INF = 2147483647;
int n,m,s,cnt = 0;
int head[100005],vis[100005],dis[100005];
struct edge
{
int dis,to,next; //dis记载路径赋值,to表示子节点,next表示前一个兄弟节点
};
edge e[200005]; // 链式前向星储存有向图
//e一位表示一条路径
struct data1
{
int dis,now;
bool operator <(const data1 &x)const
{
return this->dis > x.dis;
} //重载运算符来构建小顶堆 ,如果要构建维护大顶堆那么改为 return this->dis < x.dis即可
};
priority_queue<data1>q; //直接用自带的优先队列,这样就不用自己进行heapify维护
void add_edge(int u,int v,int d)
{
e[++cnt].dis = d;
e[cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt; //head用于记录每一个节点的最后一个字节点的编号
}
void dijkstra()
{
for(int i=1;i<=n;i++) dis[i] = INF;
dis[s] = 0;//初始化,一开始未走过的点都INF表示正无穷
q.push((data1){0,s});
while(!q.empty())
{
data1 x = q.top();//x.now指的是现在在处理的点的坐标
q.pop();
if(vis[x.now]!=0) continue;//因为dis非负,所以已走过的点不会再走
vis[x.now] = 1;
for(int i=head[x.now];i!=0;i=e[i].next) // i指的是第几条路
{
if(dis[e[i].to] > dis[x.now] + e[i].dis)
{
dis[e[i].to] = dis[x.now] + e[i].dis; //松弛操作
q.push((data1){dis[e[i].to],e[i].to});//将更新之后的子节点的dis存入q中找最小
}
}
}
}
int main()
{
cin>>n>>m>>s;
for(int i=1;i<=m;i++)
{
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
add_edge(u,v,d);
}
dijkstra();
for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
return 0;
}