PAT(甲级)2019年秋季考试 7-4 Dijkstra Sequence (30 分) 凌宸1642
PAT(甲级)2019年秋季考试 7-4 Dijkstra Sequence (30 分)
题目描述:
Dijkstra's algorithm is one of the very famous greedy algorithms. It is used for solving the single source shortest path problem which gives the shortest paths from one particular source vertex to all the other vertices of the given graph. It was conceived by computer scientist Edsger W. Dijkstra in 1956 and published three years later.
In this algorithm, a set contains vertices included in shortest path tree is maintained. During each step, we find one vertex which is not yet included and has a minimum distance from the source, and collect it into the set. Hence step by step an ordered sequence of vertices, let's call it Dijkstra sequence, is generated by Dijkstra's algorithm.
On the other hand, for a given graph, there could be more than one Dijkstra sequence. For example, both { 5, 1, 3, 4, 2 } and { 5, 3, 1, 2, 4 } are Dijkstra sequences for the graph, where 5 is the source. Your job is to check whether a given sequence is Dijkstra sequence or not.
译:Dijkstra 算法是很有名的贪心算法之一。它用于解决单源最短路径问题,该问题给出从一个特定源顶点到给定图的所有其他顶点的最短路径。它由计算机科学家 Edsger W. Dijkstra 于 1956 年构思,并于三年后发表。
在该算法中,维护一个包含最短路径树中包含的顶点的集合。 在每一步中,我们找到一个尚未包含的顶点,并且与源的距离最小,并将其收集到集合中。 因此,一个有序的顶点序列,我们称之为 Dijkstra 序列,是由 Dijkstra 算法逐步生成的。
另一方面,对于给定的图,可能有多个 Dijkstra 序列。 例如,{ 5, 1, 3, 4, 2 } 和 { 5, 3, 1, 2, 4 } 都是图的 Dijkstra 序列,其中 5 是源。 你的工作是检查给定的序列是否是 Dijkstra 序列。
Input Specification (输入说明):
Each input file contains one test case. For each case, the first line contains two positive integers Nv (≤10 3) and Ne (≤10 5), which are the total numbers of vertices and edges, respectively. Hence the vertices are numbered from 1 to Nv.
Then Ne lines follow, each describes an edge by giving the indices of the vertices at the two ends, followed by a positive integer weight (≤100) of the edge. It is guaranteed that the given graph is connected.
Finally the number of queries, K, is given as a positive integer no larger than 100, followed by K lines of sequences, each contains a permutationof the Nv vertices. It is assumed that the first vertex is the source for each sequence.
All the inputs in a line are separated by a space.
译:每个输入文件包含一个测试用例,对于每种情况,第一行包含两个整数Nv (≤10 3) 和 Ne (≤10 5), 分别代表顶点总数和边的总数。因此,顶点从 1 到 N 编号。
接下来 Ne 行,每行给出一条边的描述:边的端点的索引号以及一个表示边权 weight (≤100) 的整数。题目保证给定的图是联通的。
最后是查询次数 K ,一个不超过 100 的正整数,接下来 K 行,每行包含一个 Nv 个顶点的排列,默认第一个顶点是每个序列的起点。
所有在一行中的输入数字都用一个空格隔开。
Output Specification (输出说明):
For each of the K sequences, print in a line Yes
if it is a Dijkstra sequence, or No
if not.
译:对于 K 个序列中的每一个序列,如果它是一个 Dijkstra 序列,则打印 Yes
否则打印 No
。
Sample Input (样例输入):
5 7
1 2 2
1 5 1
2 3 1
2 4 1
2 5 2
3 5 1
3 4 1
4
5 1 3 4 2
5 3 1 2 4
2 3 4 5 1
3 2 1 5 4
Sample Output (样例输出):
Yes
Yes
Yes
No
The Idea:
题目意思很简单,可惜考试的时候没有做出来,其实就是规定一个图,然后给定一些顶点访问序列,判断该序列是否可以是 Dijkstra
算法过程中遍历产生的序列。
其实可以套 Dijkstra
算法的模板,奈何我太菜了,想不起来,唉!
The Codes:
#include<bits/stdc++.h>
using namespace std ;
const int maxn = 1010 ;
const int inf = 0x3f3f3f3f ;
int g[maxn][maxn] ;
int d[maxn] ;
bool vis[maxn] ;
int nv , ne , k ;
bool isDijkstraSeq(vector<int> num){
// 初始化
fill(d , d + maxn , inf) ;
memset(vis , false, sizeof(vis)) ;
d[num[1]] = 0 ;
// n - 1 重循环
for(int i = 1 ; i < nv ; i ++){
int minv = inf ;
set<int> st ;
for(int j = 1 ; j <= nv ; j ++){ // 找当前最小的 d[j]
if(vis[j] == false && d[j] < minv){ // 更新 d[j]
st.clear() ;
st.insert(j) ;
minv = d[j] ;
}else if(vis[j] == false && d[j] == minv) st.insert(j) ; // 相同 d[j] 加入备选
}
int u = num[i] ;
if(!st.count(u)) return false ;
vis[u] = true ;
// 松弛
for(int v = 1 ; v <= nv ; v ++){
if(vis[v] == false && g[u][v] != inf && d[u] + g[u][v] < d[v]){
d[v] = d[u] + g[u][v] ;
}
}
}
return true ;
}
int main(){
fill(g[0] , g[0] + maxn * maxn , inf) ;
scanf("%d%d" , &nv , &ne) ;
int a , b , c ;
for(int i = 0 ; i < ne ; i ++){ // 输入图
scanf("%d%d%d" , &a , &b , &c) ;
g[b][a] = g[a][b] = c ;
}
scanf("%d" , &k) ;
for(int i = 0 ; i < k ; i ++){
vector<int> num(nv + 1) ;
for(int j = 1 ; j <= nv ; j ++) scanf("%d" , &num[j]) ;
if(isDijkstraSeq(num)) printf("Yes\n") ;
else printf("No\n") ;
}
return 0 ;
}
The Result :
原文地址:https://www.cnblogs.com/lingchen1642/p/15227373.html
- 程序员必知之SEO
- 进程监控工具supervisor 启动Mongodb
- 祭奠那些年,我弃坑的开源轮子
- 这些奇技浮巧,助你优化前端应用性能
- Stepping.js——两步完成前后端分离架构设计
- 我的职业是前端工程师【十】客户端存储艺术:数据存储与模型
- 【开源】2md:将复制的内容、网页转成 markdown
- React Native 持续部署实践— push 代码构建出新版的 Growth
- 技巧 - 如何好一个 Git 提交信息及几种不同的规范
- React、Vue、Ember 及其他前端开发者,请暂缓更新到 Chrome 59 浏览器
- 微软开源全新的文档生成工具DocFX
- 使用 MimeKit 和 MailKit 发送邮件
- 使用 React Native 重写大型 Ionic 应用后,我们想分享一下这八个经验
- 基于OWin的Web服务器Katana发布版本3
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【一天一大 lee】查找常用字符 (难度:简单) - Day20201014
- 金九银十准备换场地?对标腾讯T3的Android高级工程师面试大纲及时雨来了
- 【一天一大 lee】两两交换链表中的节点 (难度:中等) - Day20201013
- 【一天一大 lee】二叉搜索树的最小绝对差 (难度:简单) - Day20201012
- 有奖互动 | 腾讯云开发者社区 3 周年庆,我过生日,送你们礼物 ~
- 【一天一大 lee】分割等和子集 (难度:中等) - Day20201011
- 【一天一大 lee】寻找两个正序数组的中位数 (难度:困难) - Day20201003
- 【一天一大 lee】颜色分类 (难度:中等) - Day20201007
- 【一天一大 lee】树中距离之和 (难度:困难) - Day20201006
- 在Spring项目中以多线程的方式并发执行,异步处理任务。解决统计、累加类业务的例子。
- 【十分钟教会你汇编】MIPS编程入门
- 实践中如何优化MySQL(收藏)
- Framework掌握不全被面试官怼?Android字节跳动大牛的精编解析笔记带你系统学习!
- 路由策略中的IP-Prefix你了解多少?
- 路由策略——Route-policy