首页 > 试题广场 >

【编程】短最优升级路径 题目描述:游戏网站提供

[问答题]

【编程】短最优升级路径


题目描述:游戏网站提供若干升级补丁,每个补丁大小不一,玩家要升级到最新版,如何选择下载哪些补丁下载量最小。

输入:

第一行输入                第一个数为用户版本 第二个数为最新版本,空格分开

接着输入N行补丁数据       第一个数补丁开始版本 第二个数为补丁结束版本 第三个数为补丁大小,空格分开

输出:

对于每个测试实例,输出一个升级路径以及最后实际升级的大小

样例输入:

1000 1050

1000 1020 50

1000 1030 70

1020 1030 15

1020 1040 30

1030 1050 40

1040 1050 20

样例输出:

1000->1020->1040->1050(100)

迪杰斯特拉最短路径算法 建立邻接矩阵,标识版本间的来去路线,求最初版本到最末版本之间的最短路径。
在dijkstra算法模板的基础上加上一个pre数组,用于记录该节点的上一个节点,即该点是经过哪一点才到达该点的。pre数组具体在边松弛的过程中进行重新赋值,松弛成功就将pre值记录k点,及该点是由起点经过k点后所得到的。最后把pre数组中的值递归输出一遍即可。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=10000;
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f
map<int,int> mp,rmp;
int road[maxn][maxn];
int dis[maxn];
bool vis[maxn];
int pre[maxn];
int n;
 
void dijkstra(int s,int e)
{//s为起点,e为终点
    memset(vis, false, sizeof(vis));//标记是否求出最短路径
    vis[s] = true;//标记起点到这一点的最小距离已经求出
    for(int i = 1; i < n; i++){
        dis[i] = road[s][i];//初始化起点到每一个点的距离
        pre[i]=s;//初始化路径,每个点的上一个点为起点
    }
    for(int u = 1; u < n-1; u++)
    {
        int minD =inf ,k = -1;
        for(int i = 1; i< n; i++)
        {   //寻找没有访问过的最短路
            if(!vis[i]&&dis[i]<minD)
            {
                k = i;//记录下标
                minD = dis[i];//记录最小值
            }
        }
        if(k==e)    break;
        vis[k] = true;//标记已经访问过
        //松弛操作
        for(int i = 1; i< n; i++)
        {
            if(!vis[i]&&dis[k]+road[k][i]<dis[i])
            {
                dis[i]=dis[k]+road[k][i];
                pre[i]=k;
            }//if
        }//for
    }
}
 
void print(int cur){
    if(cur==1){
        printf("%d",rmp[cur]);
        return ;
    }
    print(pre[cur]);
    printf("->%d",rmp[cur]);
}
 
int main(){
    int start,end;
    n=1;
    scanf("%d%d",&start,&end);
    rmp.clear();
    mp.clear();
 
    mp[start]=n;
    rmp[n]=start;
    n++;
 
    mp[end]=n;
    rmp[n]=end;
    n++;
 
    int N=(end-start)/10;
    memset(road,INF,sizeof road);
 
    for(int i=0;i<=N;i++){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        if(!mp[u]) {
            mp[u]=n;
            rmp[n]=u;
            n++;
        }
        if(!mp[v]) {
            mp[v]=n;
            rmp[n]=v;
            n++;
        }
        road[mp[u]][mp[v]]=road[mp[v]][mp[u]]=min(road[mp[v]][mp[u]],w);
    }
/*
    for(int i=1;i<n;i++){
        for(int j=1;j<n;j++)
        printf("%d  ",road[i][j]==INF?-1:road[i][j]);
        printf("\n");
    }
*/
    dijkstra(mp[start],mp[end]);
    if(dis[mp[end]]==INF)
        printf("-1");
    else
    {
        print(mp[end]);
        printf("(%d)\n",dis[mp[end]]);
    }
    return 0;
}
---------------------
作者:紫芝
来源:CSDN
原文:https://blog.csdn.net/qq_40507857/article/details/84029480
版权声明:本文为博主原创文章,转载请附上博文链接!
编辑于 2018-11-13 15:20:38 回复(0)
类似带权的有向图
发表于 2018-01-20 10:28:27 回复(0)
迪杰斯特拉最短路径算法 建立邻接矩阵,标识版本间的来去路线,求最初版本到最末版本之间的最短路径。
发表于 2017-10-16 13:55:22 回复(4)

Python解题思路,用递归,单次递归,按顺序判断开始版本,结束版本,大小,每输入一组补丁信息,即进行递归,和上一次递归的结果进行比较,两个相同则不存,开始相等,结束相同则替换,前后都不同则互换位置,补丁大小同理

发表于 2018-08-06 21:52:22 回复(0)
mm
发表于 2018-05-06 22:44:32 回复(0)
倒推
发表于 2018-04-18 14:58:37 回复(0)
不懂
发表于 2017-12-31 16:39:47 回复(0)
找到用户版本到最新版本的所有通路,比较权值。
发表于 2017-10-09 23:39:15 回复(0)
目测用递归,每次找出最新版前一个距离最小的版本,直到初始版本开始返回
发表于 2017-10-08 13:24:16 回复(0)
🤔压根看不懂怎么实现啊。
发表于 2017-09-18 15:05:02 回复(1)
😐
发表于 2017-09-02 22:41:47 回复(1)
只是用手机浏览了一下题,感觉是求两点间的最短路径,实现的话,不考虑效率我会先找出要求两节点间的所有路径,中间要考虑带环的路径,简单使用一个栈记录路径,不断更新极值。
发表于 2017-09-01 22:13:11 回复(0)