华为机试题练习-Dijkstra求最短路径

本市有N条公交线路(1…N),分别对应票价pn,可以连通本市M(1…M)个地点,小明想从地点x换乘公交到地点y,请帮助他找到最省钱的换乘路线。
地点个数M不超过100个,公交车线路个数N不超过100,票价取值区间为2-10元,公交车换乘有优惠,每次换乘可省1元。公交车只设始发站和终点站,中途不能下车;公交车始发站和终点站可以互换;不需要考虑公交车乘坐时间;用例会保证输入的格式正确性。
输入描述:第1行:地点总个数 公交线路总条数
第2行:公交线路号1 始发站 终点站 票价
第N+1行:公交线路号N 始发站 终点站 票价
最后一行:出发地 目的地

输入描述:
如下输入描述:总共有4个地点,5条公交线路;第1条公交线路连通地点1和地点2,票价3元;第2条公交线路连通地点1和地点3,票价3元;第3条公交线路连通地点1和地点4,票价4元;第4条公交线路连通地点2和地点3,票价5元;第5条公交线路连通地点3和地点4,票价3元;小明从地点1到地点3,找出最省钱的线路。
4 5
1 1 2 3
2 1 3 3
3 1 4 4
4 2 3 5
5 3 4 3
1 3

输出描述:
1.如果找不到换乘路线,则输出NA
2.如果找到最省钱换乘路线,则输出总花费

示例1 输入输出示例仅供调试,后台判题数据一般不包含示例
输入:
4 5
1 1 2 3
2 1 3 3
3 1 4 4
4 2 3 5
5 3 4 3
1 3
输出
3
 

#include <iostream>
#include <vector>
#include<stack>
#define M 50
#define N 50
using namespace std;

typedef struct node
{
    int matrix[N][M];      //邻接矩阵 
    int n;                 //顶点数 
    int e;                 //边数 
}MGraph;

void DijkstraPath(MGraph *g, int* dist, int* path, int v0)   //v0表示源顶点 
{
    int i, j, k;
    //bool* visited = (bool*)malloc(sizeof(bool) * g.n);
    vector<bool> visited(g->n, false);
    for (i = 0; i < g->n; i++)     //初始化 
    {
        if (g->matrix[v0][i] > 0 && i != v0)
        {
            dist[i] = g->matrix[v0][i];
            path[i] = v0;     //path记录最短路径上从v0到i的前一个顶点 
        }
        else
        {
            dist[i] = INT_MAX;    //若i不与v0直接相邻,则权值置为无穷大 
            path[i] = -1;
        }
        visited[i] = false;
        path[v0] = v0;
        dist[v0] = 0;
    }
    visited[v0] = true;
    for (i = 1; i < g->n; i++)     //循环扩展n-1次 
    {
        int min = INT_MAX;
        int u = 0;
        for (j = 0; j < g->n; j++)    //寻找未被扩展的权值最小的顶点 
        {
            if (visited[j] == false && dist[j] < min)
            {
                min = dist[j];
                u = j;
            }
        }
        visited[u] = true;
        for (k = 0; k < g->n; k++)   //更新dist数组的值和路径的值 
        {
            if (visited[k] == false && g->matrix[u][k] > 0 && (min - 1 + g->matrix[u][k]  < dist[k]))
            {
                dist[k] = min + g->matrix[u][k] - 1;
                path[k] = u;
            }
        }
    }
}

void showPath(int* path, int v, int v0)   //打印最短路径上的各个顶点 
{
    stack<int> s;
    int u = v;
    while (v != v0)
    {
        s.push(v);
        v = path[v];
    }
    s.push(v);
    while (!s.empty())
    {
        cout << s.top() << " ";
        s.pop();
    }
}

int main()
{
    int n = 0;
    int e = 0;     //表示输入的顶点数和边数 
    
    while (cin >> n >> e && e != 0)
    {
        int i, j;
        int s, t, w;      //表示存在一条边s->t,权值为w
        MGraph g;
        int v0;
        int vdis;
        int* dist = (int*)malloc(sizeof(int) * n);
        int* path = (int*)malloc(sizeof(int) * n);
        for (i = 0; i < N; i++)
            for (j = 0; j < M; j++)
                g.matrix[i][j] = 0;
        g.n = n;
        g.e = e;
        //int j = 0;
        for (i = 1; i <= e; i++)
        {
            //j = i + 1;
            cin >> i >> s >> t >> w;
            g.matrix[s-1][t-1] = w;
        }
        cin >> v0>>vdis;        //输入源顶点 
        v0--;
        vdis--;
        MGraph* graph = &g;
        DijkstraPath(graph, dist, path, v0);
        cout << dist[vdis] << endl;
        /*
        for (i = 0; i < n; i++)
        {
            if (i != v0)
            {
                showPath(path, i, v0);
                cout << dist[i] << endl;
            }
        }
        */
        
        
    }
    return 0;
}

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值