B类 洛谷 P4779

B类 洛谷 P4779

题意:

给定一个 NNN 个点,MMM 条有向边的带非负权图,请你计算从 SSS 出发,到每个点的距离。

数据保证你能从 SSS 出发到任意点。

分析:

输入样例#1:
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
输出样例#1:
0 2 4 3

求从1到其他所有点的最短距离,用dijkstra做

最基本模板

代码:

#include<bits/stdc++.h>
using namespace std;

#define maxn 100010
#define maxm 500010
#define INF 0x7fffffff

int head[maxn],cnt,n,m,s,vis[maxn],dis[maxn];

struct Edge{     
    int u,v,w,next;
}edge[maxm];

struct node{    //堆节点 
    int w,pos;
    bool operator<(const node &x)const{
        return w>x.w;
    }
};

priority_queue<node>q;    //

inline void add(int u,int v,int w){        //链式前向星
    edge[++cnt].u=u;
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt;
}

void dijkstra(){
    for(int i=1;i<=n;i++){
        dis[i]=INF;
    }
    dis[s]=0;    // 赋初值 s到s的距离为0
    q.push((node){0,s});    // 把源点扔进堆里
    while(!q.empty()){
        node x=q.top();    // 取堆顶
        q.pop();    // 弹堆
        int u=x.pos;
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=head[u];i;i=edge[i].next){
            int v=edge[i].v;
            if(dis[v]>dis[u]+edge[i].w){
                dis[v]=dis[u]+edge[i].w;    // 松弛操作
                if(!vis[v]){
                    q.push((node){dis[v],v});
                }
                
            }
        }
    }
}

int main(){
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1,x,y,z;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);    // 加单向边
    }
    dijkstra();
    for(int i=1;i<=n;i++){
        printf("%d ",dis[i]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zhyyyy/p/9966820.html