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;
}

原文地址:https://www.cnblogs.com/kzbin/p/9205256.html