hiho 23 最短路径 一(Dijstra)

问题描述

单源最短路径。
http://hihocoder.com/contest/hiho23/problem/1

解决方法

算法复杂度: 顶点个数n, 边个数m, O(n*m)

#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int N, M, S, T;
enum {maxn = 1000+5, MAX_INT= 1<<30};
struct E{
    int n;
    int dis;
};
vector<E> g[maxn];
struct Node{
    bool vis;
    int dis;
};
Node MinDis[maxn];
int main()
{
    //freopen("in.txt", "r", stdin);
    scanf("%d %d %d %d", &N, &M, &S, &T);
    memset(MinDis, 0, sizeof(MinDis));
    MinDis[S].vis = true;
    MinDis[S].dis = 0;
    for (int i=0; i< M; i++)
    {
        int a, b, dis;
        scanf("%d %d %d", &a, &b, &dis);
        g[a].push_back(E{b, dis});
        g[b].push_back(E{a, dis});
    }
    while(1){
        int minPos = 0;
        int minDis = MAX_INT;
        for (int i=1; i<=N; i++){
            if (MinDis[i].vis)
            {
                for (int j=0; j< g[i].size(); j++)
                {
                    if (MinDis[g[i][j].n].vis == false && MinDis[i].dis + g[i][j].dis < minDis)
                    {
                        minPos = g[i][j].n;
                        minDis = MinDis[i].dis + g[i][j].dis;
                    }
                }
            }
        }
        MinDis[minPos].vis = true;
        MinDis[minPos].dis = minDis;
        if (minPos == T)
            break;
    }
    printf("%d\n", MinDis[T].dis);
    return 0;
}

使用堆优化的Dijstra
复杂度O(mlogm) m为边的个数;

#include <bits/stdc++.h>
using namespace std;
enum {maxn = 1000+5};
class E{
public:
    E(int bb, int l):b(bb), len(l){};
    int b;
    int len;
};
class cmp{
public:
    bool operator()(E a, E b)
    {
        return a.len > b.len;
    }

};
vector<E> G[maxn];
int sp[maxn];
int N, M, S, T;
int main()
{
    scanf("%d %d %d %d", &N, &M, &S, &T);
    for (int i=0; i< M; i++)
    {
        int a, b, l;
        scanf("%d %d %d", &a, &b, &l);
        G[a].push_back(E(b, l));
        G[b].push_back(E(a, l));
    }
    memset(sp, -1, sizeof(sp));
    sp[S] = 0;
    priority_queue<E, vector<E>, cmp> A;
    int last = S;
    while(sp[T]<0)
    {
        // add last's E;
        for (int i=0; i< G[last].size(); i++)
            if (sp[G[last][i].b] < 0)
                A.push(E(G[last][i].b, sp[last]+ G[last][i].len));
        E now(1, 1);
        for(now = A.top(), A.pop(); sp[now.b] >=0; now = A.top(), A.pop())
            ;
        last = now.b;
        sp[now.b] = now.len;
    }
    printf("%d\n", sp[T]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值