*【51nod - 1459】迷宫游戏(记录双向权值的Dijkstra单源最短路)

题干:

你来到一个迷宫前。该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你就可以得到这个分数。还有若干双向道路连结这些房间,你沿着这些道路从一个房间走到另外一个房间需要一些时间。游戏规定了你的起点和终点房间,你首要目标是从起点尽快到达终点,在满足首要目标的前提下,使得你的得分总和尽可能大。现在问题来了,给定房间、道路、分数、起点和终点等全部信息,你能计算在尽快离开迷宫的前提下,你的最大得分是多少么?

Input

第一行4个整数n (<=500), m, start, end。n表示房间的个数,房间编号从0到(n - 1),m表示道路数,任意两个房间之间最多只有一条道路,start和end表示起点和终点房间的编号。 
第二行包含n个空格分隔的正整数(不超过600),表示进入每个房间你的得分。 
再接下来m行,每行3个空格分隔的整数x, y, z (0 输入保证从start到end至少有一条路径。

Output

一行,两个空格分隔的整数,第一个表示你最少需要的时间,第二个表示你在最少时间前提下可以获得的最大得分。

Sample Input

3 2 0 2
1 2 3
0 1 10
1 2 11

Sample Output

21 6

解题报告:

       此题采用邻接矩阵的方式储存图,加一个维护ans数组。

AC代码: 

#include<bits/stdc++.h>using namespace std;
const int MAX = 505;
const int INF = 0x3f3f3f3f;
int maze[505][505];
bool vis[MAX];
int dis[505],ans[505];
int val[505];
int n,m,st,ed;
struct Point {int pos,w;
};
void Dijkstra(int u,int v) {dis[u] = 0;int all = n, minw = INF, minv;
//	for(int i = 0; i<n; i++) dis[i] = maze[u][i];ans[u] = val[u];for(int k = 1; k<=n; k++) {minw = INF;minv = u;for(int i = 0; i<n; i++) {if(vis[i] ) continue;if(dis[i] <minw) {minv = i;minw = dis[i];}}vis[minv] = 1;if(minv == v) break;for(int i = 0; i<n; i++) {if(vis[i] == 0 && maze[minv][i] !=INF) {if(dis[i] > dis[minv] + maze[minv][i]) {dis[i] = min(dis[i],dis[minv]+maze[minv][i]);ans[i] = ans[minv] +val[i];}else if(dis[i]==dis[minv]+maze[minv][i]){ans[i]=max(ans[i],ans[minv]+val[i]);//若路径花费相等,点权值取较大的。}	}}}
//	if(dis[v] !=INF) printf("%d %d\n",dis[v],ans[v]);
//	else printf("-1\n");} 
void init() {memset(ans,0,sizeof(ans));memset(maze,INF,sizeof(maze));memset(dis,INF,sizeof(dis));memset(vis,0,sizeof(vis));memset(val,0,sizeof(val));
}
int main()
{int u,v,w;while(~scanf("%d%d%d%d",&n,&m,&st,&ed) ) {init();for(int i = 0; i<n; i++) {scanf("%d",&val[i]);}while(m--) {scanf("%d%d%d",&u,&v,&w);maze[u][v] = maze[v][u] = w;}Dijkstra (st,ed);}return 0 ;
}
//9:13 

AC代码2:(用dfs路径还原)(还未看。。。。)

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
const int INF=1e9+7;
const int maxm=505;
int cost[maxm][maxm],dis[maxm],vis[maxm],w[maxm],s,e,n,m,ans=0;
vector<int>p[maxm];
void dijkstra();
void dfs(int k,int sum);
int main()
{int i,j,k,sum,x,y,z;scanf("%d%d%d%d",&n,&m,&s,&e);s++;e++;for(i=1;i<=n;i++){for(j=1;j<=n;j++)cost[i][j]=INF;}for(i=1;i<=n;i++)scanf("%d",&w[i]);for(i=1;i<=m;i++){scanf("%d%d%d",&x,&y,&z);cost[x+1][y+1]=cost[y+1][x+1]=z;}dijkstra();/*for(i=1;i<=n;i++){for(j=0;j<p[i].size();j++)printf("%d ",p[i][j]);printf("\n");}*/dfs(e,0);printf("%d %d\n",dis[e],ans);return 0;
}
void dijkstra()
{int i,j,k,u,v;memset(vis,0,sizeof(vis));for(i=1;i<=n;i++)dis[i]=INF;dis[s]=0;while(true){int v=-1;for(i=1;i<=n;i++){if(!vis[i] && (v==-1 || dis[i]<dis[v]))v=i;}if(v==-1)break;vis[v]=1;for(i=1;i<=n;i++){if(dis[i]>dis[v]+cost[v][i]){//printf("%d %d %d %d\n",v,i,dis[i],dis[v]+cost[v][i]);p[i].clear();dis[i]=dis[v]+cost[v][i];p[i].push_back(v);}else if(dis[i]==dis[v]+cost[v][i])p[i].push_back(v);}}//for(i=1;i<=n;i++)//printf("%d ",dis[i]);//printf("\n");
}
void dfs(int k,int sum)
{sum+=w[k];if(k==s){ans=max(ans,sum);return;}for(int j=0;j<p[k].size();j++)dfs(p[k][j],sum);
}

总结:

   1.还是对Dijkstra算法不是很熟。。。小地方错一堆,比如函数刚开始,(被注释掉的)那个初始化,显然不能加啊,因为你这样让u到u的距离也成了INF了!而且加上这句也不会有什么优化作用。。。如果非要加初始化的话,那就把dis[u]  = 0,放到他后面。

  2. 当时在想  对于这个题  f(minv == v) break;  这句话是不是不应该加? 后来深刻理解了一下,这句话的含义是:因为第一步for筛选出了一个点minv,并且把这个点当成完成点了,第二个for在进行扩展,所以既然这个点是完成点,那么他的状态值都是完成值,大家对这个值只能读不能写(因此说是dp思想?还是贪心思想来着。。。),所以此时加上这句f(minv == v) break;也是没错的。

   3.看题解,并没有写if(vis[i] == 0 && maze[minv][i] !=INF),想想也是,这一步只是优化了时间,并不影响答案的正确性,因为你有while(all--),所以函数还是有出口的。

   4.对于这个题,法1,对maze初始化的时候不能

这样,具体为什么自己思考一下。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/441971.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法--背包九讲(详细讲解+代码)

背包九讲 目录 第一讲 01背包问题 第二讲 完全背包问题 第三讲 多重背包问题 第四讲 混合三种背包问题 第五讲 二维费用的背包问题 第六讲 分组的背包问题 第七讲 有依赖的背包问题 第八讲 泛化物品 第九讲 背包问题问法的变化 附&#xff1a;USACO中的背包问题 前…

java中白盒测试用例_基于JAVA开发的中国象棋游戏的开发与研究白盒测试用例.doc...

中国象棋白盒测试用例文件状态当前版本V1.0草稿作 者梁世聪完成日期2012/6/17文档模板SSP-VER-T13-V1.0密 级变更历史版本完成日期变更记录作者批准签字V1.02012/6/17无梁世聪梁世聪目 录目录1 目的12 范围13 被测模块列表14 模块逻辑结构14.1 模块逻辑结构图14.2 模块功能定义…

【POJ - 1502】MPI Maelstrom(Dijkstra单源最短路--求一点到其余个点的最小值的最大值)

题干&#xff1a; BIT has recently taken delivery of their new supercomputer, a 32 processor Apollo Odyssey distributed shared memory machine with a hierarchical communication subsystem. Valentine McKees research advisor, Jack Swigert, has asked her to ben…

java 强制清除缓存_IDEA强制清除Maven缓存的方法示例

重新导入依赖的常见方式下面图中的刷新按钮&#xff0c;在我的机器上&#xff0c;并不能每次都正确导入pom.xml中写的依赖项&#xff0c;而是导入之前pom.xml的依赖(读了缓存中的pom.xml)。当然除了这些&#xff0c;还可以下面这样&#xff1a;存在的问题上面虽然是重新导入Mav…

ACM算法--spfa算法--最短路算法

求单源最短路的SPFA算法的全称是&#xff1a;Shortest Path Faster Algorithm。 SPFA算法是西南交通大学段凡丁于1994年发表的。 从名字我们就可以看出&#xff0c;这种算法在效率上一定有过人之处。 很多时候&#xff0c;给定的图存在负权边&#xff0c;这时类似…

knn算法python理解与预测_理解KNN算法

KNN主要包括训练过程和分类过程。在训练过程上&#xff0c;需要将训练集存储起来。在分类过程中&#xff0c;将测试集和训练集中的每一张图片去比较&#xff0c;选取差别最小的那张图片。如果数据集多&#xff0c;就把训练集分成两部分&#xff0c;一小部分作为验证集(假的测试…

【POJ-3259】 Wormholes(判负环,spfa算法)

题干&#xff1a; While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Eac…

【HihoCoder - 1550】顺序三元组(思维)

题干&#xff1a; 给定一个长度为N的数组A[A1, A2, ... AN]&#xff0c;已知其中每个元素Ai的值都只可能是1, 2或者3。 请求出有多少下标三元组(i, j, k)满足1 ≤ i < j < k ≤ N且Ai < Aj < Ak。 Input 第一行包含一个整数N 第二行包含N个整数A1, A2, ... …

joptionpane java_Java JOptionPane

Java JOptionPane1 Java JOptionPane的介绍JOptionPane类用于提供标准对话框&#xff0c;例如消息对话框&#xff0c;确认对话框和输入对话框。这些对话框用于显示信息或从用户那里获取输入。JOptionPane类继承了JComponent类。2 Java JOptionPane的声明public class JOptionPa…

【POJ - 3268 】Silver Cow Party(Dijkstra最短路+思维)

题干&#xff1a; One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; roa…

【HDU - 3342】Legal or Not(拓扑排序)

题干&#xff1a; ACM-DIY is a large QQ group where many excellent acmers get together. It is so harmonious that just like a big family. Every day,many "holy cows" like HH, hh, AC, ZT, lcc, BF, Qinz and so on chat on-line to exchange their ideas.…

java 股票 代码_Java中利用散列表实现股票行情的查询_java

---- 在java中&#xff0c;提供了一个散列表类Hashtable&#xff0c;利用该类&#xff0c;我们可以按照特定的方式来存储数据&#xff0c;从而达到快速检索的目的。本文以查询股票的收盘数据为例&#xff0c;详细地说明java中散列表的使用方法。一、散列表的原理---- 散列表&am…

deepin部署python开发环境_deepin系统下部署Python3.5的开发及运行环境

deepin系统下部署Python3.5的开发及运行环境1 概述本人小白一枚&#xff0c;由于最近要学习python接口自动化测试&#xff0c;所以记录一下相关学习经过及经验&#xff0c;希望对跟我一样小白的朋友可以有所帮助。2 下载在python官网下载指定平台下的python3.5的环境wget https…

【HDU - 2066】:一个人的旅行(Dijkstra算法)

题干&#xff1a; 虽然草儿是个路痴&#xff08;就是在杭电待了一年多&#xff0c;居然还会在校园里迷路的人&#xff0c;汗~),但是草儿仍然很喜欢旅行&#xff0c;因为在旅途中 会遇见很多人&#xff08;白马王子&#xff0c;^0^&#xff09;&#xff0c;很多事&#xff0c;还…

for相关 java_Java学习之for循环相关知识梳理

for循环是编程语言中一种循环语句&#xff0c;是Java程序员日常工作中的重要组成部分。循环语句由循环体及循环的判定条件两部分组成&#xff0c;其表达式为&#xff1a;for(单次表达式;条件表达式;末尾循环体){中间循环体&#xff1b;}。拉勾IT课小编为大家分析如何使用这一属…

【HDU - 3790】最短路径问题(DIjkstra算法 双权值)

题干&#xff1a; 给你n个点&#xff0c;m条无向边&#xff0c;每条边都有长度d和花费p&#xff0c;给你起点s终点t&#xff0c;要求输出起点到终点的最短距离及其花费&#xff0c;如果最短距离有多条路线&#xff0c;则输出花费最少的。 Input 输入n,m&#xff0c;点的编号…

【POJ - 3037】Skiing (Dijkstra算法)

题干&#xff1a; Bessie and the rest of Farmer Johns cows are taking a trip this winter to go skiing. One day Bessie finds herself at the top left corner of an R (1 < R < 100) by C (1 < C < 100) grid of elevations E (-25 < E < 25). In or…

java web权限设计数据权限范围_JavaWeb 角色权限控制——数据库设计

相信各位读者对于角色权限管理这个需求并不陌生。那么是怎么实现的呢&#xff1f;今天小编来说道说道&#xff01;1、首先我们来进行数据库的设计&#xff0c;如何设计数据库是实现权限控制的关键&#xff1a;1)用户表&#xff1a;id&#xff1a;主键、自增、intname&#xff1…

modbus与硬件对接Java_java中modbus协议连接

modbus在java中的使用&#xff0c;首先maven的pom中引入modbus4j包com.infiniteautomationmodbus4j3.0.32. 我们创建类&#xff1a;ModBus4JTCPClient&#xff0c;创建ModbusMaster连接对象&#xff0c;以及读取寄存器方法package io.powerx.test;import org.apache.commons.la…

【51Nod-1100】 斜率最大(贪心)☆双排序

题干&#xff1a; 平面上有N个点&#xff0c;任意2个点确定一条直线&#xff0c;求出所有这些直线中&#xff0c;斜率最大的那条直线所通过的两个点。 &#xff08;点的编号为1-N&#xff0c;如果有多条直线斜率相等&#xff0c;则输出所有结果&#xff0c;按照点的X轴坐标排…