#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define re register
#define maxn 200010
using namespace std;
int head[maxn],vis[maxn],s,cnt,dis[maxn],n,m,a,b,c;
struct Edge{
int v,w,nxt;
}e[maxn<<2];
inline void add(int u,int v,int w)
{
e[++cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
struct node{
int u,d;
bool operator <(const node&rhs) const{
return rhs.d<d;
}
};
void dijkstra()
{
//memset(dis,0x3f3f3f3f,sizeof(dis));
dis[s]=0;
priority_queue<node> q;
q.push((node){s,0});
//vis[s]=1;
while(!q.empty())
{
node f=q.top();
q.pop();
int now=f.u,dd=f.d;
if(vis[now])
continue;
vis[now]=1;
for(int i=head[now];i;i=e[i].nxt)
{
int ev=e[i].v;
if(dis[ev]>dis[now]+e[i].w)
{
dis[ev]=dis[now]+e[i].w;
if(!vis[ev])
{
q.push(node{ev,dis[ev]});
}
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(int i = 1; i <= n; ++i)dis[i] = 0x7fffffff;
for(re int i=1;i<=m;++i)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
dijkstra();
for(re int i=1;i<=n;++i)
printf("%d ",dis[i]);
return 0;
}
这里补一下一直困惑的结构体重组操作:
结构体重载就相当于(cmp)函数进行排序
bool operator <(const node&rhs) const{
return rhs.d<d;
标准格式如上,上句话的意思是:一个结构体比另一个结构体小当且仅当这个结构体的(d)大于另一个结构体的(d),(rhs)相当于别的结构体
又因为堆默认大根堆,从大到小排序,那么反过来(d)就从小到大排序了。