最短路径问题(SPFA)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define INF 0x6fffffff
using namespace std;

const int maxn = 1000;
const int maxm = 1000000;

typedef struct node{
    int w;
    int to;
    int next;
}NODE;

int dist[maxn];
NODE edge[maxm];
int head[maxn];
bool visit[maxn];
int queue[maxn];
int outque[maxn];
int num = 0;
int s = 0;
int n, m;

bool SPFA(){
    int i, k, iq;
    int top;
    for(i = 0; i <= n; i++){
        dist[i] = INF;
    }
    iq = 0;
    queue[iq++] = s;
    visit[s] = true;//入队
    dist[s] = 0;
    i = 0;
    while(i != iq){
        top = queue[i];
        visit[top] = false;//出队
        outque[top]++; //记录出队的次数
        if(outque[top] > n) { return false; }
        k = head[top];
        while( k >= 0){
            if(dist[edge[k].to] > dist[top] + edge[k].w){
                dist[edge[k].to] = dist[top] + edge[k].w;
                if(!visit[edge[k].to]){
                    visit[edge[k].to] = true;//标记入队
                    queue[iq++] = edge[k].to;
                }
            }
            k = edge[k].next;
        }
        i++;
    }
    return true;
}

void output_result(){
    for(int i = 1; i <= n; i++){
        printf("%d\n", dist[i]);
    }
}

void init(){
    num = 0;
    memset(visit, false, sizeof(visit));
    memset(queue, 0, sizeof(queue));
    memset(outque, 0, sizeof(outque));
    memset(dist, 0, sizeof(dist));
    memset(head, -1, sizeof(head));
}

int main()
{
    int a = 0, b = 0, c = 0;
    while(scanf("%d%d", &n, &m)!=EOF){
        init();
        for(int i = 0; i < m; i++){
            scanf("%d%d%d", &a, &b, &c);
            edge[num].w = c;
            edge[num].to = b;
            edge[num].next = head[a];
            head[a] = num;
            num++;
        }
        cout << "please input a source:" << endl;
        scanf("%d", &s);
        bool res = SPFA();
        if(res){
            output_result();
        }
        return 0;
    }
}
/******************
SPFA(Shortest Path Faster Algorithm)
输入数据来自:
算法导论P362
5 10
1 2 6
1 3 7
2 3 8
2 4 5
2 5 -4
3 4 -3
3 5 9
4 2 -2
5 4 7
5 1 2
1
**************/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值