洛谷 P1359 租用游艇

题目描述

长江游艇俱乐部在长江上设置了 nn 个游艇出租站 1,2,\cdots,n1,2,⋯,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站 ii 到游艇出租站 jj 之间的租金为 r(i,j)r(i,j)(1\le i\lt j\le n1≤i<j≤n)。试设计一个算法,计算出从游艇出租站 11 到游艇出租站 nn 所需的最少租金。

输入格式

第一行中有一个正整数 nn,表示有 nn 个游艇出租站。接下来的 n-1n−1 行是一个半矩阵 r(i,j)r(i,j)(1\le i<j\le n1≤i<j≤n)。

输出格式

输出计算出的从游艇出租站 11 到游艇出租站 nn 所需的最少租金。

输入输出样例

输入 #1复制

3
5 15
7

输出 #1复制

12

说明/提示

n\le 200n≤200,保证计算过程中任何时刻数值都不超过 10^6106。

原题链接->传送门

依次更新从1到每个节点的最短距离,最后求出到最后一个节点n的距离,开始敲完代码测试题目给的数据结果倒是对了,但我感觉交上去应该不会过,自己画了图换了数据果然有问题,后面再改,换了好多组数据测都没什么问题了,但是交上去只有42分。 

 

 

下面是错误代码和测试数据: 

#include <bits/stdc++.h>
using namespace std;

const int inf = 1e9 + 5;
const int N   = 205;//n<=200
int vis[N];//节点访问标记数组
int low[N];//记录最短路径的数组
int Map[N][N];//图的储存数组
int n;//游艇出租站数量
 
int Dijkstra(int begin, int end)//dijkstra算法,传入起点和终点
{
    // 初始化
    for (int i = 1; i <= n; i++)
	{
        low[i] = inf;
        vis[i] = false;//初始化每个节点的标记为空 
    }
    low[begin] = 0;
    vis[begin] = true;//源节点
	 
    for (int i = 2; i <= n; i++)
	{
		low[i] = Map[begin][i];//初始化最短距离为直接距离,这里是最少租金
	}
	
	/*-------------------------------------------------------------------------------------------------*/
    for (int i = 2; i <= n; i++)
	{
        // 找到一个最短的,并且记录下来
        int Min = inf, idx = -1;//初始化
        for (int j = i; j <= n; j++)
		{
            if (low[j] < Min)
			{
                Min = low[j];
                idx = j;
            }
        }
        vis[idx] = true;//查找未访问的low[ i ]的最小值,记录最小下标index并记m_len=low[ index ],
		//标记已访问visit[ index ] = true,直到所有visit数组均为true,low[ end ]为所求值
		cout << "i=" << i << " Min=" << Min << " idx=" << idx << endl ;
        // 更新
        for (int j = 2; j <= n; j++)
		{
            if (low[j] > Min + Map[idx][j])
			{
				printf("Map[%d][%d] = %d\n",idx,j,Map[idx][j]);
                low[j] = Min + Map[idx][j];
                vis[false];
            }
			cout << "low[" << j << "]=" << low[j] << endl ;
        }
    }
	/*-------------------------------------------------------------------------------------------------*/
    return low[end];//返回最少租金 
}
 
int main()
{
    cin >> n ;//n个游艇出租站 
    
    for(int i = 1 ; i <= n ; i++)//将Map数组初始化为0 
    {
    	for(int j = 1 ; j<= n ; j++)
    	{
    		Map[i][j] = 0 ;
		}
	}
	
    for (int i = 1 ; i <= n-1 ; i++)//n-1行半矩阵 
	{
        for(int j = i+1; j <= n ; j++)
        {
        	cin >> Map[i][j] ;//代表第i个游艇站到第j个游艇站的租金
		}
    }
    /*for (int i = 1 ; i <= n-1 ; i++)//n-1行半矩阵 
	{
        for(int j = i+1; j <= n ; j++)
        { 
			printf("第%d个游艇站到第%d个游艇站的租金=",i,j);
        	cout << Map[i][j] <<endl;//代表第i个游艇站到第j个游艇站的租金
		}
    }*/
    cout << Dijkstra(1,n) ;//游艇出租站 1 到游艇出租站 n 所需的最少租金
    
    return 0;
}

/*
测试数据1:
3
5 15
7
结果1:12 
测试数据2: 
5
1 4 6 20
7 6 10
3 7
2
结果2:
8 
测试数据3:
5
1 4 8 20
7 6 10
3 7
2 
结果3:
9 
测试数据4:
5
2 4 8 20
7 6 10
3 7
2 
结果4:
9 
*/ 

//用了标记数组后的,更离谱,只有32分
#include <bits/stdc++.h>
using namespace std;

const int inf = 1e9 + 5;
const int N   = 205;//n<=200
int vis[N];//节点访问标记数组
int low[N];//记录最短路径的数组
int Map[N][N];//图的储存数组
int n;//游艇出租站数量
 
int Dijkstra(int begin, int end)//dijkstra算法,传入起点和终点
{
    // 初始化
    for (int i = 1; i <= n; i++)
	{
        low[i] = inf;
        vis[i] = false;//初始化每个节点的标记为空 
    }
    low[begin] = 0;
    vis[begin] = true;//源节点
	 
    for (int i = 2; i <= n; i++)
	{
		low[i] = Map[begin][i];//初始化最短距离为直接距离,这里是最少租金
	}
	
	/*-------------------------------------------------------------------------------------------------*/
    for (int i = 2; i <= n; i++)
	{
        // 找到一个最短的,并且记录下来
        int Min = inf, idx = -1;//初始化
        for (int j = i; j <= n; j++)
		{
            if (!vis[j] && low[j] < Min)
			{
                Min = low[j];
                idx = j;
            }
        }
        vis[idx] = true;//查找未访问的low[ i ]的最小值,记录最小下标index并记m_len=low[ index ],
		//标记已访问visit[ index ] = true,直到所有visit数组均为true,low[ end ]为所求值
		//cout << "i=" << i << " Min=" << Min << " idx=" << idx << endl ;
        //更新
        for (int j = 2; j <= n; j++)
		{
            if (low[j] > Min + Map[idx][j])
			{
				//printf("Map[%d][%d] = %d\n",idx,j,Map[idx][j]);
                low[j] = Min + Map[idx][j];
                //vis[false];
            }
			//cout << "low[" << j << "]=" << low[j] << endl ;
        }
    }
	/*-------------------------------------------------------------------------------------------------*/
    return low[end];//返回最少租金 
}
 
int main()
{
    cin >> n ;//n个游艇出租站 
    
    for(int i = 1 ; i <= n ; i++)//将Map数组初始化为0 
    {
    	for(int j = 1 ; j<= n ; j++)
    	{
    		Map[i][j] = 0 ;
		}
	}
	
    for (int i = 1 ; i <= n-1 ; i++)//n-1行半矩阵 
	{
        for(int j = i+1; j <= n ; j++)
        {
        	cin >> Map[i][j] ;//代表第i个游艇站到第j个游艇站的租金
		}
    }
    /*for (int i = 1 ; i <= n-1 ; i++)//n-1行半矩阵 
	{
        for(int j = i+1; j <= n ; j++)
        { 
			printf("第%d个游艇站到第%d个游艇站的租金=",i,j);
        	cout << Map[i][j] <<endl;//代表第i个游艇站到第j个游艇站的租金
		}
    }*/
    cout << Dijkstra(1,n) ;//游艇出租站 1 到游艇出租站 n 所需的最少租金
    
    return 0;
}

呜呜呜,实在是改不动了,小花看完我的代码帮我改了一些细节,先不说了,我要肝题了555~,今晚回家才发现题组明早截至,一整个愣住

AC代码:

#include <bits/stdc++.h>
using namespace std;

const int inf = 1e9 + 5;
const int N   = 205;//n<=200
int vis[N];//节点访问标记数组
int low[N];//记录最短路径的数组
int Map[N][N];//图的储存数组
int n;//游艇出租站数量

int Dijkstra(int begin, int end)//dijkstra算法,传入起点和终点
{
    // 初始化
    for (int i = 1; i <= n; i++)
    {
        low[i] = inf;
        vis[i] = false;//初始化每个节点的标记为空
    }
    low[begin] = 0;
    vis[begin] = true;//源节点

    for (int i = 1; i <= n; i++)
    {
        low[i] = Map[begin][i];//初始化最短距离为直接距离,这里是最少租金
    }
    for (int i = 1; i <= n; i++)
    {
        // 找到一个最短的,并且记录下来
        int Min = inf, idx = -1;//初始化
        for (int j = 1; j <= n; j++)
        {
            if (!vis[j] && low[j] < Min)
            {
                Min = low[j];
                idx = j;
            }
        }
        vis[idx] = true;
        if(idx == -1) //不能连接
            break;
        for (int j = 1; j <= n; j++)
        {
            if (!vis[j] && (low[j] > Min + Map[idx][j]))
            {
                low[j] = Min + Map[idx][j];

            }
        }
    }
    return low[end];
}

int main()
{
    cin >> n ;//n个游艇出租站

    for(int i = 0 ; i <= n ; i++)//将Map数组初始化为0
    {
        for(int j = 0 ; j<= n ; j++)
        {
            if(i==j)
                Map[i][j] = 0 ;
            else
                Map[i][j] = inf;
        }
    }

    for (int i = 1 ; i <= n-1 ; i++)//n-1行半矩阵
    {
        for(int j = i+1; j <= n ; j++)
        {
            cin >> Map[i][j] ;//代表第i个游艇站到第j个游艇站的租金
        }
    }
    cout << Dijkstra(1,n);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值