长江游艇俱乐部在长江上设置了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;
}
输入输出示例