hdu 3790 最短路径问题

题目描述

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

输入

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

输出

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

样例输入

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

样例输出

9 11

还是用Dijkstra算法找到最短路,只是多一步判断,当在找最短路的松弛过程中,路程相等时比较所用的花费大小,选择花费小的

#include
#include
#define INF 0x3f3f3f3f
int e[1010][1010],cost[1010][1010],book[1010],dis[1010],c[1010];
int n,m,s,t;
void dijkstra(int v0)
{
    for(int i=1; i<=n; i++)
    {
        dis[i]=e[v0][i];  //更新v0到i距离
        c[i]=cost[v0][i]; //更新v0到i花费
        book[i]=0;
    }
    book[v0]=1;  //v0点加入集合book,标记为1
    dis[v0]=0;
    for(int i=1; i<=n-1; i++) //从顶点v0确定n-1条最短路径
    {
        int min=INF,u;
        for(int j=1; j<=n; j++)
        {
            if(book[j]==0&&dis[j]c[u]+cost[u][v])  //比较走不同路花费的大小
                    c[v]=c[u]+cost[u][v];
            }
        }
    }

}
int main()
{
    int a,b,c1,d;
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)
            break;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++) //初始化
                e[i][j]=INF;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d%d",&a,&b,&c1,&d);
            if(e[a][b]>c1)  //避免题中会给相同顶点,不同路程的点,此时选路程小的
            {
                           //如1 2 3
                           //  1 2 5
                e[a][b]=c1;
                e[b][a]=c1;
                cost[a][b]=d;
                cost[b][a]=d;
            }
            else if(e[a][b]==c1&&cost[a][b]>d)//同上,//避免题中会给相同路程,不同花费的点,此时选花费小的
            {
                                     //如1 2 3 4
                                     //  1 2 3 10
                cost[a][b]=d;
                cost[b][a]=d;
            }
        }
        scanf("%d%d",&s,&t);
        dijkstra(s);
        printf("%d %d\n",dis[t],c[t]);
    }
    return 0;
}

你可能感兴趣的:(图论)