题目

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。
输入格式:
输入第一行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0 ~ (N−1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。
第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。
输出格式:
第一行输出最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出结尾不能有多余空格。
输入样例:
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2
输出样例:
2 60
0 1 3

解析

超级典型的dijkstra算法,多了一个计算路径数量和召集最多人数,把迪杰斯特拉算法中间那个交换的写长一点,还有,其实用深度优先剪枝法也能做这种题,也是稍微修改一下剪枝的方式就好了。(不过不推荐用深搜,因为深搜的时间复杂度高,容易出现不能过机的情况)

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int inf = 999999999;
int N, M, S, D;
int map[550][550];
int val[550], dis[550], vis[550], cnt[550], sum[550], pre[550];
//点的权值   距S距离   标记      路径数量  最大救援队  前驱
int tmp, tmp2, a, b, c;
//临时变量五兄弟
void path(int d){               //通过头递归的形式输出路径if(pre[d] != -1) {path(pre[d]);printf("%d ", pre[d]);}
}
void input(){cin >> N >> M >> S >> D;for(tmp = 0; tmp < N; tmp++) {cin >> val[tmp];}for(tmp = 0; tmp < N; tmp++) {for(tmp2 = 0; tmp2 < N; tmp2++) {if(tmp == tmp2)map[tmp][tmp2] = 0;elsemap[tmp][tmp2] = inf;}}for(tmp = 0; tmp < M; tmp++) {cin >> a >> b >> c;map[a][b] = c;          //两边都赋值一下map[b][a] = c;}for(tmp = 0; tmp < N; tmp++) {  //初始化dis[tmp] = inf;vis[tmp] = 0;cnt[tmp] = 0;sum[tmp] = 0;pre[tmp] = -1;}dis[S] = 0;     //初始化起始点vis[S] = 1;     //视自身已访问过cnt[S] = 1;     //起点到其本身方式为1sum[S] = val[S];
}
void dijkstra(){for(tmp = 0; tmp < N; tmp++){int min_val = inf, min_sign = S;for(tmp2 = 0; tmp2 < N; tmp2++){if(vis[tmp2] == 0 && min_val > dis[tmp2]){      //在未访问过的里面选取最小min_val = dis[tmp2];min_sign = tmp2;}}vis[min_sign] = 1;          //修改访问标记for(tmp2 = 0; tmp2 < N; tmp2++){if(vis[tmp2] == 0) {if(dis[tmp2] > dis[min_sign] + map[min_sign][tmp2]) {       //若存在更短路径dis[tmp2] = dis[min_sign] + map[min_sign][tmp2];        //修改点a到这个点距离sum[tmp2] = sum[min_sign] + val[tmp2];          //修改召集的人数cnt[tmp2] = cnt[min_sign];  //方式等于到达前驱的方式pre[tmp2] = min_sign;       //储存路径}else if(dis[tmp2] == dis[min_sign] + map[min_sign][tmp2]) {     //若存在相同长度路径cnt[tmp2] = cnt[min_sign] + cnt[tmp2]; //两种方式距离相等,则方式数相加if(sum[tmp2] < sum[min_sign] + val[tmp2]) {  //能获得更大的救援,则更新sum[tmp2] = sum[min_sign] + val[tmp2];pre[tmp2] = min_sign;}}}}}
}
void output(){cout << cnt[D] << " " << sum[D] << endl;path(D);cout << D << endl;
}
int main()
{input();dijkstra();output();
}

深搜示范

这题采用深搜最后一个案例会不过,我还特地写了一下做个案例,后面的迪杰斯特拉算法,我就不写另外的深搜来做范例了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int inf = 999999999;
int N, M, S, D;
int map[550][550];
int val[550], vis[550], min_pre[550];
//点的权值   标记路径  最短路径
int min_dis, max_val, all, value, len;
//最短距离 最大权值 距离 权值 数量
//临时变量五兄弟
void input(){cin >> N >> M >> S >> D;for(int tmp = 0; tmp < N; tmp++) {cin >> val[tmp];}for(int tmp = 0; tmp < N; tmp++) {for(int tmp2 = 0; tmp2 < N; tmp2++) {if(tmp == tmp2)map[tmp][tmp2] = 0;elsemap[tmp][tmp2] = inf;}}int a, b, c;for(int tmp = 0; tmp < M; tmp++) {cin >> a >> b >> c;map[a][b] = c;          //两边都赋值一下map[b][a] = c;}for(int tmp = 0; tmp < N; tmp++){vis[tmp] = 0;min_pre[tmp] = 0;}min_dis = inf;max_val = 0;value = val[S];all = 0;vis[S] = 1;
}
void dps(int a, int step){if(a == D){if(all < min_dis){      //存在更短距离,更新min_dis = all;max_val = value;len = 1;for(int tmp = 0; tmp < N; tmp++){min_pre[tmp] = vis[tmp];}}else if(all == min_dis){        //相同长度下,道路数量加一if(value > max_val){        //如果救援队多,则更新道路max_val = value;for(int tmp = 0; tmp < N; tmp++){min_pre[tmp] = vis[tmp];}}len += 1;}}if(step > N + 1|| all > min_dis){return;}for(int tmp = 0; tmp < N; tmp++){if(vis[tmp] == 0){vis[tmp] = step;all += map[a][tmp];value += val[tmp];dps(tmp, step + 1);vis[tmp] = 0;all -= map[a][tmp];value -= val[tmp];}}
}
void output(){cout << len << " " << max_val << endl;int tmp = 0;while(1){tmp++;for(int tmp2 = 0; tmp2 < N; tmp2++){if(min_pre[tmp2] == tmp){if(tmp2 != D){cout << tmp2 << " ";}else{cout << tmp2 << endl;return;}}}}
}
int main()
{input();dps(S, 2);output();
}

点击俺返回目录

L2-001 紧急救援相关推荐

  1. PTA 【L2】紧急救援

    详解代码,反正是Dijkstra的应用,问题很多 当时蚌埠住了 //#pragma GCC optimize(3, "Ofast", "inline") #in ...

  2. 天体赛练习集 简要题解 - L2

    目录 001 - 紧急救援 002 - 链表去重 003 - 月饼 004 - 这是二叉搜索树吗? 005 - 集合相似度 006 - 树的遍历 007 - 家庭房产 008 - 最长对称子串 009 ...

  3. 一文读懂——全局注意力机制(global attention)详解与代码实现

    废话不多说,直接先上全局注意力机制的模型结构图. 如何通过Global Attention获得每个单词的上下文向量,从而获得子句向量呢?如下几步: 代码如下所示: x = Embedding(inpu ...

  4. 团队程序设计天梯赛考点内容总结(15分以上题)

    L1: L1-002 打印沙漏 (20 分) 字符模拟 L1-003 个位数统计 (15 分) 字符模拟 L1-005 考试座位号 (15 分) 模拟 L1-006 连续因子 (20 分) 数学因数分 ...

  5. 中正平和的机器人学笔记——4. 雅可比矩阵(附MTALB代码)

    1. 基础知识 基础知识主要是希望大家回顾一下大学物理里讲的速度矢量和角速度矢量部分的知识,用矢量形式去表示,还有叉乘的相关知识,这些我就不赘述了. 想象存在坐标系{A}和{B},把{B}固连在某一刚 ...

  6. 深度学习3:手动实现L2正则化(L2 Regularization)

    在神经网络中,正则化的作用是防止过拟合,本文将结合一个实例来讲解神经网络中的L2正则化,并手动(不使用框架)实现出来. 先来看代码运行结果: 增加L2正则化之前 增加L2正则化之后: L2正则化为:λ ...

  7. 团体程序设计天梯赛 L2 题目合集

    前言 发现自己还能再参加一次天梯赛,在高兴之余,决定把在赛前将所有的天梯赛真题过一遍,希望自己可以取得理想的成绩.目前 L1 的题目已经刷完,打算在赛前刷完 L2 的题目. 本来想 L2 的题目都写个 ...

  8. l2的最优回归_大白话5分钟带你走进人工智能-第15节L1,L2几何解释和Ridge等回归...

    第15节 L1和L2正则几何解释和Ridge,Lasso,Elastic Net回归 上一节中我们讲解了L1和L2正则的概念,知道了L1和L2都会使不重要的维度权重下降得多,重要的维度权重下降得少,引 ...

  9. 人工智能必备数学知识· 学习笔记 ·001【线性回归,最小二乘法梯度下降法】

    注:笔记 来自课程 人工智能必备数学知识 Tips①:只是记录从这个课程学到的东西,不是推广.没有安利 Tips②:本笔记主要目的是为了方便自己遗忘查阅,或过于冗长.或有所缺省.或杂乱无章,见谅 Ti ...

  10. 【CCCC】PAT : 团体程序设计天梯赛-练习集 L2 答案,题解,附代码

    [CCCC]PAT : 团体程序设计天梯赛-练习集 L2 答案 鉴定完毕,全部水题 ヾ(•ω•`)o 知识点分类(32): 1.树锯结构(9):二叉树的存储,编号,遍历顺序转换,求深度,底层节点,从底 ...

最新文章

  1. IT规划的企业应用实践(6)研究背景 之 企业信息化建设的诉求
  2. 是否finally块总是用Java执行?
  3. JZOJ 5264. 【NOIP2017模拟8.12A组】化学
  4. 【Vscode】调试DotNet Core代码
  5. django-redis中redis.conf配置详细说明
  6. c语言时间错误的是什么意思,C语言中,如何验证输入日期的正确性!~
  7. oracle表空间 设置,Oracle表空间怎么设置和管理
  8. Python递归文件夹遍历所有文件夹及文件
  9. python生成簇_使用Python复现SIGKDD2017的PAMAE算法(并行kmedoids算法)
  10. hdu 4560 拆点最大流 ***
  11. 一个项目部署多个节点会导致锁失效么_一文看透 Redis 分布式锁进化史(解读 + 缺陷分析)...
  12. smarty 模板 php,PHP smarty模板
  13. 一文读懂物联网的关键技术有什么?
  14. python之excel多表合并
  15. 计算机应用软件弹窗消除,去除电脑弹窗广告的4种方法
  16. matlab如何看历史,matlab创建有价值历史纪录.txt 源代码在线查看 - Matlab创建有价值历史纪录(完整版),matlab 常用的命令集锦。 资源下载 虫虫电子下载站...
  17. 记一次笔记本电脑百度云盘无法连接网络问题
  18. php怎么把中文转,PHP如何将中文转为拼音?
  19. iOS关于加载图片的几种方式选择
  20. oracle 关键字 enable,Oracle之表示约束状态的关键字Enable/Disable/Validate/Novalidate

热门文章

  1. 【电子杂志制作软件】云展网教程 | 编辑书橱标题、密码、打开方式、同步文件夹
  2. 关于上传文件时,服务器选择列表为空的解决办法
  3. 软件测试面试:拿到一个版本(产品),如何开展测试?
  4. 《电子计算机机房设计规范》(GB50174-93)
  5. 《长三角区域大数据发展报告(2018)》在杭发布
  6. 来自卡内基梅隆计算机科学系主任的回复
  7. 基于Web的校园互助平台设计与实现
  8. T3-登陆系统管理提示 invalid encrypted string
  9. mysql normsinv_软件教程热搜榜_最新软件教程热门新闻_软件教程资讯大全-PC下载网资讯网...
  10. Python数据分析前景如何