游艇出租问题

长江游艇俱乐部在长江上设置了n个游艇出租站1,2,3…,n。游客可以在这些游艇出租站用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i<j=n。试设计一个算法,计算从游艇出租站1到出租站n所需的最少租金。

输入描述:第一行表示有n个站点,接下来n-1行是r( i ,  j)。

输出描述:输出从游艇出租站1到出租站3所需的最少租金

样例输入:

    3            //站数

    5  15     //从第1站到其他相应各站的租金

    7           //从第2站到其他相应各站的租金

样例输出:

               12

c语言完整代码

#include <stdio.h>
#include <stdbool.h>
#define MAXN 1001
#define INF 1<<30
int r[MAXN][MAXN]; // r[i][j]表示从节点i到节点j的距离(租金)
int dist[MAXN]; // dist[i]表示源点到节点i的最短距离
bool vis[MAXN]; // vis[i]表示节点i是否已经加入已确定最短路径的节点集合P
// dijkstra算法
int dijkstra(int n) {
    int i, j, k;
    for (i = 2; i <= n; i++)
        dist[i] = r[1][i]; // 初始化源点到各个节点的距离为r(1,i)
    for (i = 2; i <= n; i++)
        vis[i] = false; // 初始化所有节点还没有被访问过
    vis[1] = true; // 源点已经访问过了
    int cnt = 1; 
    while (cnt < n) { // 进行n-1次循环
        int minDist = INF;
        for (i = 2; i <= n; i++) { // 找出源点到未访问的节点中距离最小的节点k
            if (!vis[i] && dist[i] < minDist) {
                minDist = dist[i];
                k = i;
            }
        }         
        vis[k] = true; // 标记节点k已经被访问过了
        cnt++; // 访问节点数加1
        for (i = 1; i <= n; i++) { // 更新现有距离
            if (!vis[i] && dist[i] > dist[k] + r[k][i])
                dist[i] = dist[k] + r[k][i]; } }
    return dist[n]; // 返回源点到n节点的最短路径长度
}
int main() {
    int n;
    int k;
    printf("请输入总站数:\n");
    scanf("%d", &n);
    for (int i = 1; i < n; i++){
    	printf("请输入第%d站到后面各站的距离:\n",i);
        for (int j = i+1; j <= n; j++) {
            if (j == i+1){
			for(k=i+1;k<=n;k++)
			 scanf("%d", &r[i][k]); // 输入第i个站到第j个站之间的租金
			 r[k][i] = r[i][k]; 
			 	}} }
    printf("第1站到第%d站的最小距离为:\n",n);
    printf("%d\n", dijkstra(n));
    return 0;
}

输入输出示例

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值