zoukankan      html  css  js  c++  java
  • POJ 3790 最短路径问题(Dijkstra变形——最短路径双重最小权值)

    题目链接:

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

    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
     
    Source
     题意描述:
    输入顶点的个数n和道路的条数m以及起始点数s和t((1<n<=1000, 0<m<100000, s != t))
    计算并输出最短距离及其花费(如果最短路径数相同,输出花费最小)
    解题思路:
    哇,读到这个题,心想求最短路径和最小花费,直接两边DijkstraOK,直接WA。
    后来想想,先要保证路径最短,那么就先求最短路径,Dijkstra不变,只不过最后更新的时候处理一下最小花费就行了,具体处理方法见代码。
    另外,既然存在路径相同而花费不同,那么必然输入数据存在两顶点相同,路径相同,但花费不同的数据,所以输入的时候我们只保留相同情况下花费最小即可。
    题目很经典,如需了解
    最长路径最小权值 请参考博客:http://www.cnblogs.com/wenzhixin/p/7336948.html
    最短路径最大权值 请参考博客:http://www.cnblogs.com/wenzhixin/p/7406333.html
    AC代码:
     1 #include<stdio.h>
     2 int e1[1010][1010],e2[1010][1010];
     3 int inf=99999999,n,m,s,t;
     4 void Dijkstra();
     5 int main()
     6 {
     7     int i,j,t1,t2,t3,t4;
     8     while(scanf("%d%d",&n,&m), n+m != 0)
     9     {
    10         for(i=1;i<=n;i++)//全部初始化为inf 
    11             for(j=1;j<=n;j++)
    12                 e1[i][j]=e2[i][j]=inf;//i和j 
    13                 
    14         for(i=1;i<=m;i++)
    15         {
    16             scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
    17             if(e1[t1][t2] > t3)//存储的时候就去重,先保证路径最短,否则如
    18             //果相等且花费变小则更新花费 
    19             {
    20                 e1[t1][t2]=e1[t2][t1]=t3;//双向 
    21                 e2[t1][t2]=e2[t2][t1]=t4;
    22             }
    23             else if(e1[t1][t2] == t3 && e2[t1][t2] > t4)
    24             e2[t1][t2]=e2[t2][t1]=t4;
    25         }
    26         scanf("%d%d",&s,&t);
    27         
    28         Dijkstra();
    29     }
    30     return 0;
    31 }
    32 void Dijkstra()
    33 {
    34     int i,j,u,v,min,d[1010],c[1010],book[1010];
    35     for(i=1;i<=n;i++)
    36     {
    37         d[i]=e1[s][i];
    38         c[i]=e2[s][i];
    39     }
    40     for(i=1;i<=n;i++)
    41         book[i]=0;//初始化为0 
    42     book[s]=1;
    43     
    44     for(i=1;i<=n-1;i++)
    45     {
    46         min=inf;
    47         for(j=1;j<=n;j++)
    48         {//找到距离s点最近的尚未访问的点 
    49             if(!book[j] && d[j] < min)
    50             {
    51                 min=d[j];
    52                 u=j;
    53             }
    54         }
    55         book[u]=1;
    56         for(v=1;v<=n;v++)//遍历每个顶点 
    57         {
    58             if(!book[v] && e1[u][v] < inf)
    59             {//加入点U后,更新每个顶点到s的距离为最近,便于下次查找 
    60                 if(d[v] > d[u]+e1[u][v])
    61                 {//和之前的去重一样,在保证最短路径且花费减少时 才更新最小花费 
    62                     d[v]=d[u]+e1[u][v];
    63                     c[v]=c[u]+e2[u][v];
    64                 }
    65                 else if(d[v] == d[u]+e1[u][v] && c[v] > c[u]+e2[u][v])
    66                 c[v] = c[u]+e2[u][v];
    67             }
    68         }
    69     } 
    70     printf("%d %d
    ",d[t],c[t]);
    71 }
  • 相关阅读:
    多输出感知机及其梯度
    《机器学习实战》-线性回归
    《机器学习实战》-逻辑(Logistic)回归
    SQL Server 空间监测
    SQL Server 从数据库快照还原数据库
    SQL Server 创建数据库快照
    SQL Server 数据库的自动选项
    SQL Server 数据库游标选项
    SQL Server 数据库状态选项
    MYSQL 二进制还原
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/7405802.html
Copyright © 2011-2022 走看看