spfa模版

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaohaibo_/article/details/80353200

题目描述

给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

输入输出格式

输入格式:

第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。

接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。

输出格式:

一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)

输入输出样例

输入样例

4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4

输出样例

0 2 4 3
//静态临接表
#include <queue>
#include <cstdio>
#define INF 1e6
using namespace std;
const int maxn=100;
int src = 1; //源点是1号点
int n,m; //n个点,m条边

//ihead是邻接表头节点表,num记录边的序号。ihead记录的是每一个边的节点号,也就是每一个num。
int ihead[maxn],num;

//dis[i]是第i号节点距离源点的距离。
int dis[maxn],vis[maxn];

struct Edge{
    int next,to;
    int length;
}e[maxn];
//由a向b建第num条边。
void add(int a,int b,int k){
    e[++num].to = b;
    e[num].next = ihead[a];//前向
    e[num].length = k;
    ihead[a] = num;
}

void init(){
    for(int i=1;i<=n;i++)
        dis[i] = INF;
    dis[src] = 0;
}

void spfa(){
    init();
    queue<int>que;
    que.push(src);
    vis[src] = 1;
    while(!que.empty()){
        int head = que.front();
        que.pop();
        vis[head] = 0;
        //遍历head的所有邻边
        for(int i=ihead[head];i;i = e[i].next){
            int p = e[i].to;
            if(dis[p] > dis[head] + e[i].length){
                dis[p] = dis[head] + e[i].length;
                if(!vis[p]){
                    vis[p] = 1;
                    que.push(p);
                }
            }
        }
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; ++i){
        int a,b,k;
        scanf("%d%d%d",&a, &b, &k);
        add(a,b,k);
    }
    spfa();
    for(int i=1;i<=n;i++){
        if(i==src)
            printf("0 ");
        else
            printf("%d ",dis[i]);
    }
    return 0;

}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页