最优乘车问题/dijsktra最短路径算法

7 篇文章 0 订阅
3 篇文章 0 订阅

H城是一个旅游胜地,每年都有成千上万的人前来观光.为方便游客,巴士公司在各个旅游景点及宾馆、饭店等地都设置了巴士站,并开通了一些单向巴士线路。每条单向巴士线路从某个巴士站出发,依次途径若干个巴士站,最终到达终点巴士站。

阿昌最近到H城旅游,住在CUP饭店。他很想去S公园游玩。听人说,从CUP饭店到S公园可能有也可能没有直通巴士。如果没有,就要换乘不同线路的单向巴士,还有可能无法乘巴士到达。现在用整数1,2,...,n给H城的所有巴士站编号,约定CUP饭店的巴士站编号为1,S公园巴士站的编号为N。写一个程序,帮助阿昌寻找一个最优乘车方案,使他在从CUP饭店到S公园的过程中换车的次数最少。

车站:1    2    3    4    5

第一条路线:1 2 3 5

第二条路线:1 4

第三条路线:4 5

则直接选择第一条路线,换车次数最少为0

输入

第1行是一个数字M(1≤M≤100)表示开通了M条单向巴士线路,第2行是一个数字N(1<N≤500),表示共有N个车站。从第3行到第M+2行依次给出了第一条到第M条巴士线路的信息。其中第i+2行给出的是第i条巴士线路的信息,从左至右依次按行行驶顺序给出了该线路上的所有站点,相邻两个站号之间用一个空格隔开。 

输出

为最少换车次数(在0,1,…,M-1中取值),0表示不需换车即可达到。如果无法乘车达到S公园,则输出"NO"。

样例输入

2
5
1 4
2 3 4 5

样例输出

1

该题可将一趟公交车经过的站点看成一张图中连通的顶点,且站台之间的距离都为1。每换乘一次会必会使得路径长度加1(因为换乘的目的就是向终点站靠近,所以换乘后的公交到达的最远站点序号必定大于换乘前能到达的最远序号,又由于第一次换乘前至少搭过一个站点(每趟公交至少经过两个站点否则无法换乘),即初始路径为1,所以有:换乘数 = 路径-1

如:样例中 1 - 4的距离为1,2-3,2-4,2-5,3-4,4-5 的距离均为1。第一条公交:1->4,路径 = 1,换乘到第二条公交:4->5,路径 = 2。换乘数 = 路径 - 1 = 1

代码:

#include<stdio.h>
#include<string.h>
#define MAX 155
#define inf 0x3f3f3f

int map[MAX][MAX];
int dist[MAX];
bool flag[MAX];
int n,m;

void fun(int start);
int main()
{
    memset(map,inf,sizeof(int)*MAX*MAX);
    scanf("%d%d",&m,&n);
    char c;
    int len;
   while(m--)
    {
        c=1;
         len=0;
        while ((c!=-1)&&(c!='\n'))
        {
              scanf("%d",&dist[++len]);
              c=-1;
              scanf("%c",&c);
        }
        for (int j=1;j<=n;++j)
            for (int k=j+1;k<=n;++k)
                map[dist[j]][dist[k]]=1;
    }
   fun(1);
   if(map[1][n]==inf)
    printf("NO\n");
   else
    printf("%d\n",map[1][n]-1);

    return 0;
}
void fun(int start)
{
    flag[start] = true;

   for(int i = 1 ; i<=n ; i++)
    {
        int temp = start;
        int min = inf;
        for(int i = 1 ; i<=n ; i++)
        {
            if(!flag[i]&&map[start][i]<min)
            {
                min = map[start][i];
                temp = i;
            }
        }
        flag[temp] = true;
        for(int i = 1 ; i<=n ; i++)
        {
            if(!flag[i]&&map[start][temp]<inf)
            if(map[start][i]>map[start][temp]+map[temp][i])
                map[start][i] = map[start][temp]+map[temp][i];
        }
    }
}

 

 

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值