*【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,一经查实,立即删除!

相关文章

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;一小部分作为验证集(假的测试…

joptionpane java_Java JOptionPane

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

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

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

【HDU - 3714 】Error Curves (三分)

题干&#xff1a; Josephina is a clever girl and addicted to Machine Learning recently. She pays much attention to a method called Linear Discriminant Analysis, which has many interesting properties. In order to test the algorithms efficiency, she colle…

指数循环节证明

还有关键的一步忘写了phi(m)>r的注意因为ma^r*m‘’所以phi(m)>phi(a^r)>r,所以就相当于phi(m)为循环节&#xff0c;不过如果指数小于phi(m)只能直接算了。。 注意这里的m与a^r是互质的上面忘写了。。 转自https://blog.csdn.net/guoshiyuan484/article/details/787…

java语言中的类可以_java 语言中的类

类一、类类是具有相同性质的一类事物的总称, 它是一个抽象的概念。它封装了一类对象的状态和方法, 是创建对象的模板。类的实现包括两部分: 类声明和类体类的声明类声明的基本格式为:[ 访问权限修饰符]c l a s s类名[extends超类][ implments实现的接口列表]{}说 明:① 访问权限…

【POJ - 3310】Caterpillar(并查集判树+树的直径求树脊椎(bfs记录路径)+dfs判支链)

题干&#xff1a; An undirected graph is called a caterpillar if it is connected, has no cycles, and there is a path in the graph where every node is either on this path or a neighbor of a node on the path. This path is called the spine of the caterpillar …

软件设计师下午题java_2018上半年软件设计师下午真题(三)

● 阅读下列说明和Java代码,将应填入(n)处的字句写在答题纸的对应栏内。【说明】生成器( Builder)模式的意图是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。图6-1所示为其类图。【Java代码】import java.util.*&#xff1b;class Product {priv…

java细粒度锁_Java细粒度锁实现的3种方式

最近在工作上碰见了一些高并发的场景需要加锁来保证业务逻辑的正确性&#xff0c;并且要求加锁后性能不能受到太大的影响。初步的想法是通过数据的时间戳&#xff0c;id等关键字来加锁&#xff0c;从而保证不同类型数据处理的并发性。而java自身api提供的锁粒度太大&#xff0c…

【POJ - 1062】【nyoj - 510】昂贵的聘礼 (Dijkstra最短路+思维)

题干&#xff1a; 年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了&#xff0c;于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币&#xff0c;便请求酋长降低要求。酋长说&#xff1a;"嗯&#xff0c;如果…

【HDU - 5605】 geometry(水,数学题,推公式)

题干&#xff1a; There is a point PP at coordinate (x,y)(x,y). A line goes through the point, and intersects with the postive part of X,YX,Yaxes at point A,BA,B. Please calculate the minimum possible value of |PA|∗|PB||PA|∗|PB|. Input the first line…

matlab如何画函数的外包络曲线,怎样在MATLAB中划出一个函数的包络线?

沧海一幻觉下面是一系列关于MATLAB的包络线的程序&#xff1a;%这是定义了一个函数&#xff1a;function [up,down] envelope(x,y,interpMethod)%ENVELOPE gets the data of upper and down envelope of the known input (x,y).%% Input parameters:% x the abscissa of the g…

【51Nod - 1279】 扔盘子(思维)(on-p会超时)

题干&#xff1a; 有一口井&#xff0c;井的高度为N&#xff0c;每隔1个单位它的宽度有变化。现在从井口往下面扔圆盘&#xff0c;如果圆盘的宽度大于井在某个高度的宽度&#xff0c;则圆盘被卡住&#xff08;恰好等于的话会下去&#xff09;。 盘子有几种命运&#xff1a;1、…

java 内部类私有成员 能访问,为什么外部Java类可以访问内部类私有成员?

HUX布斯如果您想隐藏内部类的私有成员&#xff0c;您可以与公共成员定义一个接口&#xff0c;并创建一个实现此接口的匿名内部类。下面的例子&#xff1a;class ABC{private interface MyInterface{void printInt();}private static MyInterface mMember new MyInterface(){pr…

【POJ - 3321】 Apple Tree(dfs序 + 线段树维护 或 dfs序 + 树状数组维护)

题干&#xff1a; There is an apple tree outside of kakas house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been carefully nurturing the big apple tree. The tree has N forks which are connected by branches. …

【HDU - 1698】 Just a Hook(线段树模板 区间覆盖更新(laz标记) + 区间和查询 )

题干&#xff1a; In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of the same length. Now Pudge wants to do some operations on the hoo…

反序列化 php R类型,pikachu-PHP反序列化、XXE、SSFR

一、PHP反序列化1.1概述在理解这个漏洞前,你需要先搞清楚php中serialize()&#xff0c;unserialize()这两个函数。序列化serialize()序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象:class S{public $test"pikachu";}$snew S(); //创建一个对象…

【51nod - 前缀异或】 对前缀和的理解

题干&#xff1a; 前缀异或 基准时间限制&#xff1a;2 秒 空间限制&#xff1a;131072 KB 分值: 5 输入一个长度为n(1 < n < 100000)数组a[1], a[2], ..., a[n]。 输入一个询问数m(1 < m < 100000)和m组询问&#xff0c;每组询问形如(l, r) 对于每组询问(l, …