nuoyanli 520 Let‘s play computer game
H题
描述
xxxxxxxxx在疫情期间迷上了一款游戏,这个游戏一共有nnn个地点(编号为1——n1——n1——n),他每次从一个地点移动到另外一个地点需要消耗
一定的能量,每一个地点都有一些珠宝,输入中会把每一个地方的珠宝价值估算成一个值。
xxxxxxxxx想请聪明的你帮他找出来从编号为sss的地点,到编号为ddd的地点最小要消耗多少能量,消耗这些能量最多获得多少价值的珠宝
输入
第一行输入n,s,dn,s,dn,s,d。其意义如上描述 (n<520n<520n<520)
第二行有nnn个数XiX_iXi,比如i==1i==1i==1描述编号为1的点有珠宝价值为XiX_iXi(这里保证XiX_iXi大于等于0) (Xi<1000X_i<1000Xi<1000)
下面输入一个n∗nn*nn∗n的矩阵,比如第iii行,第j列的值为xxx,就表示从编号为iii到编号为jjj的地方距离为x (x<1000)x (x<1000)x (x<1000)
注意:这是一个单向路,即从编号为iii到编号为jjj的距离可能不等于从编号为jjj到编号为iii
输出
输出占一行,第一个数是最小要消耗多少能量,第二个数是消耗这些能量最多获得多少价值的珠宝。两个数用空格分开
输入样例 1
4 1 4
20 30 40 10
0 1 2 3
999 0 999 2
999 999 0 2
999 999 999 0
输出样例 1
3 60
输入样例 2
7 2 3
341 527 189 740 490 388 989
0 489 711 174 305 844 971
492 0 998 954 832 442 424
619 906 0 154 293 395 439
735 738 915 0 453 748 786
550 871 932 693 0 326 53
904 732 835 354 364 0 691
669 157 719 282 875 573 0
输出样例 2
998 716
提示
第一个样例解释:
解释:
把这个矩阵翻译成边
1->2 1
2->4 2
1->4 3
1->3 2
3->4 2
正确路径:1->2->4
题目正解:最短路+dfs 或 最短路+dp。
题目灵感:L2-001 紧急救援 (25分)。
题目大意描述:
让你找出来最短路径,如果最短路径有多条,那就取出来每一条路径中 所有点权值之和 最大的那个路径(点权值是什么意思?就是题目中说的每一个点的珠宝价值)
题目解法1:最短路+dfs
按照题目描述我们就需要先找出来最短路的大小,然后我们知道这个大小之后就dfs去跑图,找到每一条能从起点s到终点d的路径,然后每一条路径肯定有一个路径长度,我们只保留那个与最短路大小相等的长度的路径
然后对每一条路径在dfs过程中记录它所经过每一个点,把这些点的权值加到一起,我们设这个值为总值
那么每一条路径都有一个总值,我们只需要从中找出来最大的那个输出就行
Dfs代码如下:
void dfs(int x,int value)
{
if(x==d)
{
if(result<value)
{
result=value;
}
return;
}
for(int i=1; i<=n; ++i)
{
if(!vis[i] && dist[i]==dist[x]+G[x][i] && G[x][i])
{
vis[i]=1;
dfs(i,value+val[i]);
vis[i]=0;
}
}
}
这里我们为了避免盲目的搜索所有路径,我们可以加一个限制条件来优化dfs:
dist[i]==dist[x]+G[x][i] //dist是我们跑最短路之后跑出来的单源最短路数组
假设一条路径例如s->2->3->d,如果你dfs过程中s->2->3的长度不等于dist[3] ,那么就算dfs到终点d这条路径长度绝对不可能等于dist[d]
至于为什么这里就不多说了,自己想一下
代码:
1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #include<vector>
7 using namespace std;
8 typedef long long ll;
9 const int inf = 0x3f3f3f3f;
10 const int maxn = 550;
11 int n,m,s,d;
12 int val[maxn],vis[maxn],dist[maxn];
13 int G[maxn][maxn],result;
14 int int_rand(int min,int max)
15 {
16 return int(min+rand()%(max-min));
17 }
18 struct shudui1
19 {
20 int start,value;
21 bool operator < (const shudui1 q)const
22 {
23 return value<q.value;
24 }
25 } str1;
26 priority_queue<shudui1>r;
27 void dijkstra()
28 {
29 memset(vis,0,sizeof(vis));
30 memset(dist,inf,sizeof(dist));
31 dist[s]=0;
32 str1.start=s;
33 str1.value=0;
34 r.push(str1);
35 while(!r.empty())
36 {
37 int x,y;
38 str1=r.top();
39 r.pop();
40 x=str1.start;
41 y=str1.value;
42 if(dist[x]<y) continue;
43 for(int i=1; i<=n; ++i)
44 {
45 if((dist[x]+G[x][i]<dist[i]))
46 {
47 dist[i]=dist[x]+G[x][i];
48 str1.start=i;
49 str1.value=dist[i];
50 r.push(str1);
51 }
52 }
53 }
54 }
55 void dfs(int x,int value)
56 {
57 if(x==d)
58 {
59
60 if(result<value)
61 {
62 result=value;
63 }
64 return;
65 }
66 for(int i=1; i<=n; ++i)
67 {
68 if(!vis[i] && dist[i]==dist[x]+G[x][i] && G[x][i])
69 {
70 vis[i]=1;
71
72 dfs(i,value+val[i]);
73
74 vis[i]=0;
75 }
76 }
77 }
78 int main()
79 {
80 int u,v,w;
81 scanf("%d%d%d", &n, &s, &d);
82 for(int i = 1; i <= n; i ++)
83 {
84 scanf("%d", &val[i]);
85 }
86 for(int i = 1; i <= n; i ++)
87 {
88 for(int j = 1; j <= n; j ++)
89 {
90 scanf("%d",&G[i][j]);
91 }
92 }
93 dijkstra();
94 result=0;
95 memset(vis,0,sizeof(vis));
96 vis[s]=1;
97 dfs(s,val[s]);
98 printf("%d %d\n",dist[d],result);
99 return 0;
100 }
题目解法2:最短路+dp
题外话:这个方法其实我并没有想到,还是yzj验题之后给me说的(牛掰)
for(ll i=0; i<len; i++)
{
ll v=vec[t][i].v;
ll w=vec[t][i].w;
if(dis[t]+w<dis[v])
{
dp[v]=dp[t]+sc[v]; //当s->v的最短路径已然变得更小,那么dp值要重新赋值,而不是比较之后再赋值
dis[v]=dis[t]+w;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
else if(dis[t]+w==dis[v]) //相对于原版spay算法,这里多了一个判断。多这个判断的意义和上面第一种解法的dfs里面多一个判断那个差不多
{
if(dp[v]<dp[t]+sc[v])//这里要想给dp[v]赋值就要通过判断,因为我们要输出总值最大的那个路径
{
dp[v]=dp[t]+sc[v];
if(!vis[v])
{
vis[v]=1;
q.push(v);//如果这个点满足条件,那么我们还要把这个点放入队列,那么相比于原spay算法这个代码复杂度就要大一点,但是还是要比第一种方法复杂度低
}
}
}
}
Dp关键部分就是上面代码,也就是在spay算法的while循环里面
解释一下每一个数组:
Dis数组是存放单源最短路结果
Vis数组是用来标记某一个点是否进入队列中(等于1就代表在队列)
Dp[i]数组初值是等于i点的权值(点权值是什么意思?就是题目中说的每一个点的珠宝价值),这个数组的作用就是找出来题目第二个输出结果
Sc[]数组初值是等于i点的权值
代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 const ll maxn=2e3+5;
5 ll sc[maxn],dis[maxn],vis[maxn],ans;
6 ll dp[maxn],pre[maxn];
7 struct node
8 {
9 ll v,w;
10 } p;
11 vector<node>vec[maxn];
12 vector<ll>ve[maxn];
13 queue<ll>q;
14 void spfa(ll u)
15 {
16 memset(dis,0x3f3f3f3f,sizeof(dis));
17 memset(vis,0,sizeof(vis));
18 dis[u]=0;
19 q.push(u);
20 while(!q.empty())
21 {
22 ll t=q.front();
23 vis[t]=0;
24 q.pop();
25 ll len=vec[t].size();
26 for(ll i=0; i<len; i++)
27 {
28 ll v=vec[t][i].v;
29 ll w=vec[t][i].w;
30 if(dis[t]+w<dis[v])
31 {
32 dp[v]=dp[t]+sc[v];
33 dis[v]=dis[t]+w;
34 if(!vis[v])
35 {
36 vis[v]=1;
37 q.push(v);
38 }
39 }
40 else if(dis[t]+w==dis[v])
41 {
42 if(dp[v]<dp[t]+sc[v])
43 {
44 dp[v]=dp[t]+sc[v];
45 if(!vis[v])
46 {
47 vis[v]=1;
48 q.push(v);
49 }
50 }
51 }
52 }
53 }
54 }
55 int main()
56 {
57 ios::sync_with_stdio(false);
58 cin.tie(0);
59 ll n,s,d;
60 cin>>n>>s>>d;
61 for(ll i=1; i<=n; i++)
62 cin>>sc[i],dp[i]=sc[i];
63 ll w;
64 for(ll i=1; i<=n; i++)
65 for(ll j=1; j<=n; j++)
66 {
67 if(i==j)
68 cin>>w;
69 else
70 cin>>w,p.v=j,p.w=w,vec[i].push_back(p);
71 }
72 spfa(s);
73 cout<<dis[d]<<' '<<dp[d]<<endl;
74 }
nuoyanli 520 Let‘s play computer game的更多相关文章
- L3-007 天梯地图 (30分) 最短路+dp
最短路+dp思路:nuoyanli 520 Let's play computer game 输入样例1: 10 15 0 1 0 1 1 8 0 0 1 1 4 8 1 1 1 5 4 0 2 3 ...
- Stack switching mechanism in a computer system
A method and mechanism for performing an unconditional stack switch in a processor. A processor incl ...
- Let‘s play computer game(最短路 + dfs找出所有确定长度的最短路)
Let's play computer game Description xxxxxxxxx在疫情期间迷上了一款游戏,这个游戏一共有nnn个地点(编号为1--n1--n1--n),他每次从一个地点移动 ...
- 共享文件夹:The user has not been granted the requested logon type at this computer
场景重现 今天做一个项目测试,要用到虚拟机,于是在虚拟机(XP 32)上新建了一个共享的文件夹.然后我在Win7 机器上访问它得到如下的error 消息:
- 1Z0-053 争议题目解析520
1Z0-053 争议题目解析520 考试科目:1Z0-053 题库版本:V13.02 题库中原题为: 520.Which of the following are not disabled by de ...
- Computer assisted surgery
Computer assisted surgery (CAS) represents a surgical concept and set of methods, that use computer ...
- Computer vision labs
积累记录一些视觉实验室,方便查找 1. 多伦多大学计算机科学系 2. 普林斯顿大学计算机视觉和机器人实验室 3. 牛津大学Torr Vision Group 4. 伯克利视觉和学习中心 Pro ...
- Computer Vision: OpenCV, Feature Tracking, and Beyond--From <<Make Things See>> by Greg
In the 1960s, the legendary Stanford artificial intelligence pioneer, John McCarthy, famously gave a ...
- 数论 - Vanya and Computer Game
Vanya and his friend Vova play a computer game where they need to destroy n monsters to pass a level ...
随机推荐
- Redis 5 配置 Redis sentinel(哨兵模式)
先了解一下哨兵都 做了什么工作:Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务: * 监控(Monitoring): Sentin ...
- SQL查找连续出现的数字
基于Oracle: 题:编写一个 SQL 查询,查找所有至少连续出现三次的数字. +----+-----+ | Id | Num | +----+-----+ | 1 | 1 | | 2 | 1 | ...
- 映泰主板H100系列安装win7的各种坑
自100系列主板发布以来,windows7好像就被遗弃一样,原因就在于安装win7的时候,会出现USB设备无法使用导致无法安装的问题.主要在于Win7系统没有整合USB的XHCI驱动,而100系列芯片 ...
- kubernets之DaemonSet
一 k8s资源之DaemonSet 1.1 介绍认识DaemonSet DaemonSet可以理解为一种比较特殊的RS,DaemonSet的作用是永远保持被指定的节点只运行一个pod的副本,可用作集 ...
- Log4j日志记录
1.导入log4j的jar包 2.写log4j.properties文件,配置日志记录参数,一般参数如下所示: 第二行指定了输出日志的目录,此处用的相对路径,也可换成绝对路径: 第三行指定了输出的记录 ...
- LeetCode590. N叉树的后序遍历
题目 1 class Solution { 2 public: 3 vector<int>ans; 4 vector<int> postorder(Node* root) { ...
- CVE-2020-0796复现
今天整理资料时发现了之前存的一个cve漏洞复现过程,当时打算跟着复现来着,后来也没去复现,今天刚好有时间,所以来复现一下这个漏洞 漏洞讲解 https://www.freebuf.com/vuls/2 ...
- SAP FTP FOR ABAP programing
近来忙的不可开交,忙的一塌糊涂,呵呵,今天怀揣愧疚之心,上来分享博文一篇,算是对自己的一点安慰. 首先在SAP系统中提供了很多的FTP示例程序,如下: RSFTP001 SAPFT ...
- CodeMonkey少儿编程第2章 turnTo对象
目标 了解对象的概念 了解方法与对象的关系 掌握turnTo指令的用法 在开始本章的学习之前,我们先来复习一下上一章的知识点. 在第1章中,我们学会了在这个游戏中最简单的两个指令. step x 其中 ...
- openshift 3.11安装部署
openshift 3.11 安装部署 openshift安装部署 1 环境准备(所有节点) openshift 版本 v3.11 1.1 机器环境 ip cpu mem hostname OSsys ...