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

题目描述:
给你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\n", d[t], p[t]);
    }
    return 0;
}

posted on 2015-06-24 10:35  Alex0111  阅读(381)  评论(0编辑  收藏  举报

导航