• HDU 3790(两种权值的迪杰斯特拉算法)


    传送门:

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

    最短路径问题

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 33731    Accepted Submission(s): 9888


    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
     
    分析:
    迪杰斯特拉算法,写了很久,终于理解了这句话:
    如果最短距离有多条路线,则输出花费最少的。
    同时也要注意有重边的情况
    代码如下:
    #include<bits/stdc++.h>
    using namespace std;
    #define max_v 1005
    #define INF 99999
    int edge[max_v][max_v];
    int v[max_v][max_v];
    int n,m;
    int used[max_v];
    int dis[max_v];
    int cost[max_v];
    void init()
    {
        memset(used,0,sizeof(used));
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                edge[i][j]=INF;
                v[i][j]=INF;
            }
            dis[i]=INF;
            cost[i]=INF;
        }
    }
    void Dijkstra(int s)
    {
        for(int i=1; i<=n; i++)
        {
            dis[i]=edge[s][i];
            cost[i]=v[s][i];
        }
        dis[s]=0;
        cost[s]=0;
        for(int i=1; i<=n; i++)
        {
            int index,mindis=INF,mincost=INF;
            for(int j=1; j<=n; j++)
            {
                if(used[j]==0&&dis[j]<mindis)
                {
                    mindis=dis[j];
                    mincost=cost[j];
                    index=j;
                }
                else if(used[j]==0&&dis[j]==mindis&&cost[j]<mincost)//如果最短距离有多条路线,则输出花费最少的。
                {
                    mindis=dis[j];
                    mincost=cost[j];
                    index=j;
                }
            }
            used[index]=1;
            for(int j=1; j<=n; j++)
            {
                if(dis[index]+edge[index][j]<dis[j])
                {
                    dis[j]=dis[index]+edge[index][j];
                    cost[j]=cost[index]+v[index][j];
                }
                else if(dis[index]+edge[index][j]==dis[j])//如果最短距离有多条路线,则输出花费最少的。
                {
                    if(cost[index]+v[index][j]<cost[j])
                    {
                        cost[j]=cost[index]+v[index][j];
                    }
                }
    
            }
        }
    }
    int main()
    {
        while(~scanf("%d %d",&n,&m))
        {
            if(n==0&&m==0)
                break;
            init();
            for(int i=0; i<m; i++)
            {
                int a,b,c,d;
                scanf("%d %d %d %d",&a,&b,&c,&d);
                if(edge[a][b]>c)//预防重边
                {
                    edge[a][b]=edge[b][a]=c;
                    v[a][b]=v[b][a]=d;
                }
            }
            int x,y;
            scanf("%d %d",&x,&y);
            Dijkstra(x);
            printf("%d %d
    ",dis[y],cost[y]);
        }
    }
  • 相关阅读:
    java数组------数组基本使用和3中初始化方式
    java面向对象-------final关键字
    java面向对象------- 多态
    java面向对象------- 封装
    Android 音视频开发(五):使用 MediaExtractor 和 MediaMuxer API 解析和封装 mp4 文件
    Android 音视频开发(四):使用 Camera API 采集视频数据
    音频 PCM 数据的采集和播放
    http协议的学习
    Kotlin入门学习笔记
    RxJava笔记
  • 原文地址:https://www.cnblogs.com/yinbiao/p/9197344.html
Copyright © 2020-2023  润新知