求调,玄关

P4779 【模板】单源最短路径(标准版)

nineup @ 2024-07-26 09:15:50

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=2e5+5,N=1e5+5;
int n,m,s;
int h[M],cnt=1;
struct edge{
    int to,next,w;
}e[M];
struct node{
    int x,d;
    bool operator <(const node &a)const{
        return a.d<d;
    }
};
priority_queue <node> q;
bool vis[N];
int dis[N],pre[N];
int u,v,w;
void add(int u,int v,int w){
    e[cnt].to=v;
    e[cnt].next=h[u];
    e[cnt].w=w;
    h[u]=cnt++;
}
void way(int s,int t){
    if(t==s) printf("%d ",s);
    else{
        way(s,pre[t]);
        printf("%d ",t);
    }
}
int main(){
    cin>>n>>m>>s;
    memset(h,-1,sizeof(h));
    for(int i=1; i<=m; i++){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
    }
    for(int i=1; i<=n; i++) dis[i]=0x3f3f3f3f;
    dis[s]=0;
    q.push((node){s,0});
    while(!q.empty()){
        node k=q.top();
        q.pop();
        if(vis[k.x]) continue;
        vis[k.x]=1;
        for(int i=h[k.x]; i; i=e[i].next){
            int t=e[i].to;
            if(dis[t]>dis[k.x]+e[i].w){
                dis[t]=dis[k.x]+e[i].w;
                pre[t]=k.x;

            }
            if(!vis[t]) q.push((node){t,dis[t]});
        }
    }
    for(int i=1; i<=n; i++) printf("%d ",dis[i]);
    return 0;
}

by ericloo0921 @ 2024-07-26 10:00:07

优先队列如果不定义的话好像是默认从大到小排序吧1(应该)

我优先队列是用的pair<long long,int>,第一位存 负的dis[s],第二位存节点编号(这里用s代替),让优先队列按照默认的从大到小排序,在入队时将dis×-1,这样就能起到类似于从小到大排序的效果,在需要访问dis[s]的值的时候直接使用dis[s],不用优先队列存的 负的dis[s]就可以了



好像是没其他的问题了

by ericloo0921 @ 2024-07-26 10:01:22

@ericloo0921 不知道为什么最后一行变成代码了(


by ericloo0921 @ 2024-07-26 10:08:38

dijkstra那里的入队的代码,可以不用判断(!vis),只有优化了最短路才会入队,所以放在dis判断的里面


by nineup @ 2024-07-26 11:05:38

@ericloo0921 玄学了,关o2优化就对了


|