zoukankan      html  css  js  c++  java
  • HDU3790最短路径问题

    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

    题解:样例水过,就是不知道错在哪。。。难过可以说就是Dijkstra算法模板题,当然,除了Floyed算法外其他最短路径算法应该也可以过吧,没试吐舌头。在求最短路径的基础上求花费,其实很简单,加一个cost数组用来记录最短路径的花费。在更新最短路的时候同时更新cost数组。在有多条最短路时,选择花费最小的那条。

    #include<bits/stdc++.h>
    #define INF 0x3f3f3f3f
    const int maxn=1005;
    using namespace std;
    struct node{
        int d,p;
    }e[maxn][maxn];
    int dis[maxn],vis[maxn],cost[maxn];
    int n,m;
    int s,t;
    void init(){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(i==j) {
                    e[i][j].d=0;
                    e[i][j].p=0;
                }
                else e[i][j].d=e[i][j].p=INF;
            }
        }
    }
    void Dijkstra(){
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            dis[i]=e[s][i].d;
            cost[i]=e[s][i].p;
        }
        cost[s]=0;
        vis[s]=1;
        dis[s]=0;
        for(int i=1;i<=n;i++){
            int index=-1,minx=INF;
            for(int j=1;j<=n;j++){//寻找距离源点最近的点
                if(!vis[j]&&dis[j]<minx){
                    minx=dis[j];
                    index=j;
                }
            }
            if(index==-1) return;//没找到说明当前所有节点已全部距离源点为最短,返回。
            vis[index]=1;
            for(int j=1;j<=n;j++){
                if(!vis[j]&&e[index][j].d){//更新最短路径
                    if(dis[j]>dis[index]+e[index][j].d){//最短路只有一条的情况下,同时更新最短路和花费的钱
                        dis[j]=dis[index]+e[index][j].d;
                        cost[j]=cost[index]+e[index][j].p;
                    }else if(dis[j]==dis[index]+e[index][j].d){
                        cost[j]=min(cost[j],cost[index]+e[index][j].p);//在有多条最短路时,选择其中花费最少的那条。
                    }
                }
            }
        }
    }
    int main()
    {
        int a,b,d,p;
        while(scanf("%d%d",&n,&m)&&(n+m)){
            init();
            for(int i=1;i<=m;i++){
                scanf("%d%d%d%d",&a,&b,&d,&p);
                if(d<e[a][b].d){//最短路只有一条的情况下,同时更新最短路和花费的钱
                    e[a][b].d=e[b][a].d=d;
                    e[a][b].p=e[b][a].p=p;
                }else if(d==e[a][b].d){//在有多条最短路时,选择其中花费最少的那条。
                    e[a][b].p=e[b][a].p=min(p,e[a][b].p);
                }
            }
            scanf("%d%d",&s,&t);
            Dijkstra();
            printf("%d %d
    ",dis[t],cost[t]);
        }
        return 0;
    }
    

  • 相关阅读:
    【LeetCode】731. 图像渲染
    【LeetCode】130. 被围绕的区域
    小白之HTTP协议熟悉篇
    Java和js常用表达式
    Mysql主主复制高可用解决方案
    解决vue报错:Module build failed (from ./node_modules/_eslint-loader@2.2.1@eslint-loader/index.js): TypeError: Cannot read property 'range' of null
    centos7使用yum安装jdk并配置jdkhome
    阿里nacos安装及使用指南
    js实现给html固定区域增加水印
    MySQL安装教程
  • 原文地址:https://www.cnblogs.com/kzbin/p/9205256.html
Copyright © 2011-2022 走看看