• 考研编程练习----最短路径问题


    题目描述:
    给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
    输入:
    输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
    (1<n<=1000, 0<m<100000, s != t)
    输出:
    输出 一行有两个数, 最短距离及其花费。
    样例输入:
    3 2
    1 2 5 6
    2 3 4 5
    1 3
    0 0
    样例输出:
       9 11
    经典代码:
    #include <stdio.h>
    #define INT_MAX 0x7FFFFFFF
    #define MAX_V 1001
    #define MAX_E 1000
    int main()
    {
        int n, m, d[MAX_V], p[MAX_V], visited[MAX_V], path[MAX_E][4], s, t, minPos;
        while (scanf("%d%d", &n, &m) != EOF)
        {
            if (!n&&!m) break;
            //initialize
            for (int i = 0; i <= n; ++i)
            {
                d[i] = INT_MAX;
                p[i] = INT_MAX;
                visited[i] = 0;
            }
            //0 a,1 b,2 d,3 p
            for (int i = 0; i < m; ++i) scanf("%d%d%d%d", &path[i][0], &path[i][1], &path[i][2], &path[i][3]);
            scanf("%d%d", &s, &t);
            //algorithm start
            d[s] = 0; p[s] = 0; visited[s] = 1;
            for (int i = 0; i < m; ++i)
            {
                if (path[i][0] == s)
                {
                    d[path[i][1]] = path[i][2];
                    p[path[i][1]] = path[i][3];
                }
                else if (path[i][1] == s)
                {
                    d[path[i][0]] = path[i][2];
                    p[path[i][0]] = path[i][3];
                }
            }
            do
            {
                minPos = 0;
                for (int i = 1; i <= n; ++i)
                {
                    if (visited[i]) continue;
                    if (!minPos || d[i] < d[minPos] || (d[i] == d[minPos] && p[i] < p[minPos])) minPos = i;
                }
                if (minPos)
                {
                    int a=minPos, b;
                    for (int i = 0; i < m; i++)
                    {
                        if (path[i][0] != a&&path[i][1] != a) continue;
                        if (path[i][0] == a) b = path[i][1];
                        else if (path[i][1] == a) b = path[i][0];
                        if (visited[b]) continue;
                        if (d[a] + path[i][2] < d[b]
                            || d[a] + path[i][2] == d[b] && p[a]+path[i][3]<p[b])
                        {
                            d[b] = d[a] + path[i][2];
                            p[b] = p[a] + path[i][3];
                        }
                    }
                    visited[a] = 1;
                }
            } while (minPos);
            printf("%d %d ", d[t], p[t]);
        }
        return 0;
    }
  • 相关阅读:
    安卓监听帧动画结束
    零基础学python-13.4 文件上使用列表解析与列表解析扩展
    零基础学python-13.3 列表解析简介与步骤分解
    零基础学python-13.2 手动迭代:iter和next
    零基础学python-13.1 迭代器简介与文件迭代器
    零基础学python-12.6 使用for和zip来并行使用多个序列
    零基础学python-12.5 修改列表的误区以及使用for和range修改列表
    零基础学python-12.4 while、for与range联合使用
    零基础学python-12.3 for循环
    零基础学python-12.2 关键字pass,else,break,continue
  • 原文地址:https://www.cnblogs.com/Alex0111/p/4597056.html
Copyright © 2020-2023  润新知