1987 Problem D 最短路径

本文介绍了一种基于Dijkstra算法和SPFA算法实现寻找两点间最短路径的方法,包括算法的具体实现过程及代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题 D: 最短路径
时间限制: 1 Sec 内存限制: 32 MB
献花: 81 解决: 14
[献花][花圈][TK题库]
题目描述
有n个城市m条道路(n<1000, m<10000),每条道路有个长度,请找到从起点s到终点t的最短距离和经过的城市名。
输入
输入包含多组测试数据。
每组第一行输入四个数,分别为n,m,s,t。
接下来m行,每行三个数,分别为两个城市名和距离。
输出
每组输出占两行。
第一行输出起点到终点的最短距离。
第二行输出最短路径上经过的城市名,如果有多条最短路径,输出字典序最小的那条。若不存在从起点到终点的路径,则输出“can’t arrive”。
样例输入
3 3 1 3
1 3 3
1 2 1
2 3 1
样例输出
2
1 2 3

Dijkstra算法

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <cfloat>
#include <map>

#define INF INT32_MAX
using namespace std;

struct node
{
    int w;
    int v;
    node(int a, int b) :v(a), w(b) {  };
};

const int MaxN = 1010;
int des[MaxN], pre[MaxN];
vector<node> G[MaxN];
bool visited[MaxN];
int N;

void Dijkstra(int s)
{
    fill(des, des + N + 1, INF);
    for (int i = 0; i < N; ++i)pre[i] = i;
    memset(visited, 0,N + 1);
    des[s] = 0;

    for (int i = 1,Min,u; i <= N; ++i)
    {
        Min = INF, u = -1;
        for (int k = 1; k <= N; ++k)
        {
            if (!visited[k] && Min > des[k])
            {
                Min = des[k];
                u = k;
            }
        }

        if (u == -1)return;
        visited[u] = true;

        for (int k = 0; k < G[u].size(); ++k)
        {
            int v = G[u][k].v;
            if(!visited[v])
            {
                if (des[v] > des[u] + G[u][k].w)
                {
                    des[v] = des[u] + G[u][k].w;
                    pre[v] = u;
                }
                else if (des[v] == des[u] + G[u][k].w && pre[v] > u)
                {
                    pre[v] = u;
                }
            }
        }
    }
}


void DFS(int s, int e)
{
    if (s == e)
    {
        cout << e << " ";
        return;
    }

    DFS(s, pre[e]);
    cout << e << " ";
}


int main()
{
#ifdef _DEBUG
    freopen("data.txt", "r+", stdin);
#endif // _DEBUG

    std::ios::sync_with_stdio(false);

    int M,s,t;
    while(cin >> N >> M >> s >> t)
    {
        for (int i = 1; i <= N; ++i)
            G[i].clear();

        for (int i = 0, d = 1; i < M; ++i, d *= 2)
        {
            int u, v, w;
            cin >> u >> v >> w;
            G[u].push_back(node(v, w));
            G[v].push_back(node(u, w));
        }

        Dijkstra(s);

        if (des[t] != INF)
        {
            cout << des[t] << endl;
            DFS(s, t);
        }
        else
            cout << "can't arrive";
       cout << endl;

    }

    return 0;
}
/**************************************************************
    Problem: 1987
    User: Sharwen
    Language: C++
    Result: 升仙
    Time:103 ms
    Memory:2396 kb
****************************************************************/

SFPA算法

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <cfloat>
#include <map>

#define INF INT32_MAX
using namespace std;

struct node
{
    int w;
    int v;
    node(int a, int b) :v(a), w(b) {  };
};

const int MaxN = 1010;
int des[MaxN], pre[MaxN];
vector<node> G[MaxN];
bool isInq[MaxN];
int N;

void Dijkstra(int s)
{
    fill(des, des + N + 1, INF);
    for (int i = 0; i < N; ++i)pre[i] = i;
    memset(isInq, 0,N + 1);
    des[s] = 0;

    queue<int>que; que.push(s);
    while (que.size())
    {
        int u = que.front(); que.pop(); isInq[u] = false;
        for (auto i = 0; i < G[u].size(); ++i)
        {
            int v = G[u][i].v;
            if (des[v] > des[u] + G[u][i].w)
            {
                des[v] = des[u] + G[u][i].w;
                pre[v] = u;
                que.push(v); isInq[v] = true;
            }
            else if (des[v] == des[u] + G[u][i].w && pre[v] > u)
                pre[v] = u;
        }
    }
}


void DFS(int s, int e)
{
    if (s == e)
    {
        cout << e << " ";
        return;
    }

    DFS(s, pre[e]);
    cout << e << " ";
}


int main()
{
#ifdef _DEBUG
    freopen("data.txt", "r+", stdin);
#endif // _DEBUG

    std::ios::sync_with_stdio(false);

    int M,s,t;
    while(cin >> N >> M >> s >> t)
    {
        for (int i = 1; i <= N; ++i)
            G[i].clear();

        for (int i = 0, d = 1; i < M; ++i, d *= 2)
        {
            int u, v, w;
            cin >> u >> v >> w;
            G[u].push_back(node(v, w));
            G[v].push_back(node(u, w));
        }

        Dijkstra(s);

        if (des[t] != INF)
        {
            cout << des[t] << endl;
            DFS(s, t);
        }
        else
            cout << "can't arrive";
        cout << endl;

    }

    return 0;
}
/**************************************************************
    Problem: 1987
    User: Sharwen
    Language: C++
    Result: 升仙
    Time:117 ms
    Memory:2404 kb
****************************************************************/
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值