最短路径问题

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

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

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

示例1
输入
3 2
1 2 5 6
2 3 4 5
1 3
0 0
输出
9 11

题目解析:迪杰斯特拉计算单元最短路径,并且记录最小花费

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include<math.h>
#include<algorithm>
#include<vector>

using namespace std;
 
#define N 1001
#define INF 0x3f3f3f3f
 
int n,m,adj[N][N],cost[N][N],visit[N],lowdis[N],lowcos[N]; //adj邻接矩阵,cost花费矩阵,visit是否用过,lowdis最短距离,lowcos最少花费 
 
void dijkstra(int s, int t)
{
    memset(visit,0,sizeof(visit));
    visit[s] = 1;
    lowdis[s] = lowcos[s] = 0;
    for(int i=1;i<=n;i++)            //根据初始数据,输入s到各点的距离和花费 
        if(i != s)
        {
            lowdis[i] = adj[s][i];
            lowcos[i] = cost[s][i];
        }
    int pos = s;
    for(int i=1;i<=n;i++)
    {
        int mindis = INF;
        for(int j=1;j<=n;j++)
            if(!visit[j] && lowdis[j] < mindis)
            {
                mindis = lowdis[j];
                pos = j;
            }
        if(mindis == INF)
            break;
        visit[pos] = 1;
        for(int j=1;j<=n;j++)
            if(adj[pos][j] != INF && cost[pos][j] != INF && (lowdis[j] >= lowdis[pos] + adj[pos][j]))
            {
                if((lowdis[j] == lowdis[pos] + adj[pos][j] && lowcos[j] > lowcos[pos] + cost[pos][j]) || (lowdis[j] > lowdis[pos] + adj[pos][j]))
                    lowcos[j] = lowcos[pos] + cost[pos][j];
                lowdis[j] = lowdis[pos] + adj[pos][j];
            }
    }
    printf("%d %d\n",lowdis[t],lowcos[t]);
}
 
int main()
{
    while(scanf("%d %d",&n,&m) != EOF)
    {
        if(n == 0 && m == 0)
            break;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                adj[i][j] = cost[i][j] = INF;
        while(m--)
        {
            int a,b,d,p;
            scanf("%d %d %d %d",&a,&b,&d,&p);
            if(d < adj[a][b])              //首先是最短距离 
            {
                adj[a][b] = adj[b][a] = d;
                cost[a][b] = cost[b][a] = p;
            }
            else if(d == adj[a][b] && p < cost[a][b])     //可能多个相同的,更新为费用低的 
                cost[a][b] = cost[b][a] = p;
        }
        int s,t;
        scanf("%d %d",&s,&t);
        dijkstra(s,t);
    }
    return 0;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值