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
解题思路:解题关键先保证是最短距离,其次如果距离相等的话,再保证最小费用。首先要预处理一下,因为读入数据可能出现重边,如果不处理就会进行覆盖原来的权值,这样就出错了。
AC代码一Dijkstra:
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int INF = 0x3f3f3f3f;
  4. const int MAXN = ;
  5. int n,m,a,b,d,p,s,t,dis[MAXN],cis[MAXN],cost[MAXN][MAXN],G[MAXN][MAXN];//dis数组记录当前节点离起点的最短路径,cis数组记录当前节点离起点的最小费用,cost数组和G数组分别记录费用和节点之间的关系
  6. bool vis[MAXN];
  7. void Dijkstra(){
  8. for(int i=;i<=n;++i){//先默认初始化dis和cis为起点到各节点的最短路径和最小费用
  9. dis[i]=G[s][i];
  10. cis[i]=cost[s][i];
  11. }
  12. dis[s]=cis[s]=;vis[s]=true;//到自己的距离为0,且0花费
  13. for(int i=;i<n;++i){ //剩下遍历n-1个节点
  14. int k=-; //先标记为-1
  15. for(int j=;j<=n;++j)//查找dis中的最小权值
  16. if(!vis[j] && (k==- ||dis[j]<dis[k]))k=j;//找到最小权值的下标
  17. if(k==-)break; //说明已经全部归纳了,直接退出当前循环,否则才可以进行下面的松弛操作
  18. vis[k]=true; //该点已经归纳最短路径的集合
  19. for(int j=;j<=n;++j){//更新起点到每个节点的最短路径
  20. if(!vis[j]){ //如果还没有归纳进去
  21. if(dis[j]>dis[k]+G[k][j]){
  22. cis[j]=cis[k]+cost[k][j];
  23. dis[j]=dis[k]+G[k][j];
  24. }
  25. else if(dis[j]==dis[k]+G[k][j] && cis[j]>cis[k]+cost[k][j]) //如果当前多条最短路径,则取两者中较小费用
  26. cis[j]=cis[k]+cost[k][j];
  27. }
  28. }
  29. }
  30. }
  31. int main()
  32. {
  33. while(~scanf("%d %d",&n,&m) && (m+n)){
  34. for(int i=;i<=n;++i){
  35. for(int j=;j<=n;++j)
  36. if(i==j)G[i][j]=cost[i][j]=;//到自身的距离和费用都为0
  37. else G[i][j]=cost[i][j]=INF;//其余初始化为INF
  38. }
  39. memset(vis,false,sizeof(vis));
  40. for(int i=;i<=m;++i){
  41. scanf("%d %d %d %d",&a,&b,&d,&p);
  42. if(G[a][b]>d){//预处理,考虑到重边的情况
  43. G[a][b]=G[b][a]=d;
  44. cost[a][b]=cost[b][a]=p;
  45. }
  46. else if(G[a][b]==d && cost[a][b]>p)//如果a到b的距离等于原来的话,取最小费用
  47. cost[a][b]=cost[b][a]=p;
  48. }
  49. scanf("%d %d",&s,&t);
  50. Dijkstra();
  51. printf("%d %d\n",dis[t],cis[t]);
  52. }
  53. return ;
  54. }

AC代码二(优先队列默认最大堆实现Dijkstra迪杰斯特拉算法):

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int INF = 0x3f3f3f3f;
  4. const int MAXN = ;
  5. int n,m,a,b,d,p,s,t,dis[MAXN],cis[MAXN],cost[MAXN][MAXN],G[MAXN][MAXN];//dis数组记录当前节点离起点的最短路径,cis数组记录当前节点离起点的最小费用,cost数组和G数组分别记录费用和节点之间的关系
  6. void Dijkstra(){
  7. priority_queue< pair<int,int> > que;//最大堆优先队列
  8. dis[s]=cis[s]=;//到自己的距离为0,且0花费
  9. que.push(make_pair(-dis[s],s));//加上负号实现最大堆,便于取出最短路径
  10. while(!que.empty()){
  11. int k=que.top().second;//每次取出队首元素即最短路径
  12. que.pop();//弹出队首元素
  13. for(int i=;i<=n;++i){ //更新邻边权值最小的邻接点
  14. if(dis[i]>dis[k]+G[k][i]){
  15. cis[i]=cis[k]+cost[k][i];
  16. dis[i]=dis[k]+G[k][i];
  17. que.push(make_pair(-dis[i],i)); //如果有最小权值的邻接点,加入队列中去,记得加负号,因为这是最大堆
  18. }
  19. else if(dis[i]==dis[k]+G[k][i] && cis[i]>cis[k]+cost[k][i]) //如果当前多条最短路径,则取两者中较小费用
  20. cis[i]=cis[k]+cost[k][i];
  21. }
  22. }
  23. }
  24. int main()
  25. {
  26. while(~scanf("%d %d",&n,&m) && (m+n)){
  27. for(int i=;i<=n;++i)
  28. dis[i]=cis[i]=INF;//全部初始化为INF无穷大
  29. for(int i=;i<=n;++i){
  30. for(int j=;j<=n;++j)
  31. if(i==j)G[i][j]=cost[i][j]=;//到自身的距离和费用都为0
  32. else G[i][j]=cost[i][j]=INF;//其余初始化为INF
  33. }
  34. for(int i=;i<=m;++i){
  35. scanf("%d %d %d %d",&a,&b,&d,&p);
  36. if(G[a][b]>d){//预处理,考虑到重边的情况
  37. G[a][b]=G[b][a]=d;
  38. cost[a][b]=cost[b][a]=p;
  39. }
  40. else if(G[a][b]==d && cost[a][b]>p)//如果a到b的距离等于原来的话,取最小费用
  41. cost[a][b]=cost[b][a]=p;
  42. }
  43. scanf("%d %d",&s,&t);
  44. Dijkstra();
  45. printf("%d %d\n",dis[t],cis[t]);
  46. }
  47. return ;
  48. }

题解报告:hdu 3790 最短路径问题的更多相关文章

  1. ACM: HDU 3790 最短路径问题-Dijkstra算法

    HDU 3790 最短路径问题 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Des ...

  2. HDU - 3790 最短路径问题 (dijkstra算法)

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

  3. HDU 3790最短路径问题 [最短路最小花费]

    题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=3790] 最短路径问题 Time Limit: 2000/1000 MS (Java/Others)  ...

  4. hdu 3790 最短路径问题(双重权值,dijkstra算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 题目大意:题意明了,输出最短路径及其花费. 需要注意的几点:(1)当最短路径相同时,输出最小花费 ...

  5. hdu 3790 最短路径问题(两个限制条件的最短路)

    http://acm.hdu.edu.cn/showproblem.php?pid=3790 有两个条件:距离和花费.首先要求距离最短,距离相等的条件下花费最小. dijkstra,仅仅是在推断条件时 ...

  6. HDU 3790 最短路径问题 (最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3790 简单的最短路问题,这题听说有重边.我用spfa和dijkstra写了一遍,没判重边,速度都差不多 ...

  7. #HDU 3790 最短路径问题 【Dijkstra入门题】

    题目: 最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. hdu 3790 最短路径问题(迪杰斯特拉)

    最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  9. hdu 3790 最短路径dijkstra(多重权值)

    最短路径问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

随机推荐

  1. python之cookbook-day02

    第一章:数据结构和算法 1.2 解压可迭代对象赋值给多个变量 问题: 如果一个可迭代对象的元素个数超过变量个数时,会抛出一个 ValueError .那么 怎样才能从这个可迭代对象中解压出 N 个元素 ...

  2. 【模板】大数乘法(51nod 1027)

    #include<cstdio> #include<cstring> #include<algorithm> #define LL long long #defin ...

  3. FZU 1492 地震预测(模拟链表的应用)(Java实现)

    FZU 1492 地震预测(模拟链表的应用)(Java实现) 怀特先生是一名研究地震的科学家,最近他发现如果知道某一段时间内的地壳震动能量采样的最小波动值之和,可以有效地预测大地震的发生. 假设已知一 ...

  4. Trees on the level (二叉链表树)

    紫书:P150 uva122 Background Trees are fundamental in many branches of computer science. Current state- ...

  5. hdu 1867 kmp匹配

    #include<stdio.h> #include<string.h> #define N 100100 void getnext(int next[],char s[]) ...

  6. Spring-data-jpa 笔记(二) Repository 详解

    基础的 Repository 提供了最基本的数据访问功能,其几个子接口则扩展了一些功能.它们的继承关系如下: Repository: 是 spring Data 的一个核心接口,它不提供任何方法,开发 ...

  7. url处理函数

    function UrlOption(url) { this.url = url || ''; this.init(); this.change = function (url) { this.url ...

  8. 非常适合新手的jq/zepto源码分析01

    (function(global, factory) { // 查看这里是不是定义成模块,如果定义模块就返回 一个模块 if (typeof define === 'function' &&a ...

  9. UVa 10315 - Poker Hands

    题目:两个人手里各有五张牌,比較两牌型大小. 比較规则例如以下:(按优先级排序,优先级同样按以下内部规则比較) 1.straight-flush:同花顺,牌面连续,花色同样,按最大的值比較. 2.fo ...

  10. jq 地区(省市县区)联动菜单

    <pre name="code" class="html"><pre name="code" class="ph ...