HDU - 最短路径问题

http://acm.hdu.edu.cn/showproblem.php?pid=3790

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Problem Description

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

Input

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)

Output

输出 一行有两个数, 最短距离及其花费。

Sample Input

3 2
1 2 5 6
2 3 4 5
1 3
0 0

Sample Output

9 11

Problem solving report: 

Description: 最短路问题,给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

Problem solving: 在最短路的基础上加一个记录两个点的花费额的数组,只存两个点最小的花费额,在利用最短边松弛其它边的时候,若松弛后的边不变,松弛最小的花费额。

#include <stdio.h>
const int inf = 99999999;
int n, m, s, t, k, a, b, d, q, minn;
int vis[1010], dis[1010], map[1010][1010], cost[1010][1010];
int main()
{
    while (scanf("%d%d", &n, &m), m + n)
    {
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                if (i != j)
                    cost[i][j] = cost[j][i] = map[i][j] = map[j][i] = inf;
                else cost[i][j] = cost[j][i] = map[i][j] = map[j][i] = 0;
        for (int i = 0; i < m; i++)
        {
            scanf("%d%d%d%d", &a, &b, &d, &q);
            if (map[a][b] > d)
            {
                map[a][b] = map[b][a] = d;
                cost[a][b] = cost[b][a] = q;
            }
            else if (map[a][b] == d && cost[a][b] > q)
                cost[a][b] = cost[b][a] = q;
        }
        scanf("%d%d", &s, &t);
        for (int i = 1; i <= n; i++)
        {
            dis[i] = map[s][i];
            vis[i] = 0;
        }
        vis[s] = 1;
        for (int i = 1; i < n; i++)
        {
            minn = inf;
            for (int j = 1; j <= n; j++)
            {
                if (!vis[j] && dis[j] < minn)
                {
                    k = j;
                    minn = dis[j];
                }
            }
            vis[k] = 1;
            for (int j = 1; j <= n; j++)
            {
                if (map[k][j] < inf)
                {
                    if (!vis[j] && dis[j] > dis[k] + map[k][j])
                    {
                        dis[j] = dis[k] + map[k][j];
                        cost[s][j] = cost[s][k] + cost[k][j];
                    }
                    else if (!vis[j] && dis[j] == dis[k] + map[k][j] && cost[s][j] > cost[s][k] + cost[k][j])
                        cost[s][j] = cost[s][k] + cost[k][j];
                }
            }
        }
        printf("%d %d\n", dis[t], cost[s][t]);
    }
    return 0;
}

 

全部评论

相关推荐

个人背景:学院二本计科专业&nbsp;大二开始实习个人经历:安克创新&nbsp;、理想汽车、字节跳动碎碎念:我做事只有三分钟热度。看到进了大厂的同学,我会羡慕,也会跟着努力上进;但遇到好看的小说,我又会放下手头的事沉迷其中,之前的坚持也就中断了。我有些自卑,总觉得自己学历和外貌都不够好。之前偶然在网上受到关注,我就喜欢上了上网,因为这里有很多人认可我。但我也很在意别人的评价,偶尔看到嘲讽的言论,会触发我的自卑情绪,让我感到愤怒。有时候我会强硬地回怼,有时候又会懦弱地选择无视。我也有虚荣心。不管是拿到安克、理想还是字节的机会,我在分享的时候都会带着这份心思。我会特意强调自己学历不好,是为了衬托出过程的艰难,以此显得自己更厉害。我知道,人往往会炫耀自己缺少的东西,来掩盖内心的空洞。我总想着走捷径,不太喜欢踏踏实实地做事。找实习的时候,我花了更多时间在研究面试技巧上,而不是提升专业能力。我会反复听面试录音分析技巧,看面试教程学习怎么和不同的面试官沟通,还会每天自言自语练习语言表达,同学都觉得我有点奇怪。我的实习生涯里,侥幸和运气占了很大一部分。我总在想,如果有一天我失去了这份幸运,这些特质可能会让我一蹶不振。ps:&nbsp;很多人会问我学习路线和经验&nbsp;但是就像我上面说的&nbsp;我的实习过程靠的很多是关键节点的运气&nbsp;技术上面我可能不如很多人&nbsp;&nbsp;所以请大家理性求助和理性参考我的回答&nbsp;附上我的投递记录
我的offer在哪里...:从去年看到现在,飞升哥就是榜样
我的求职进度条
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务