PAT 甲级 1003 Emergency DFS
地址 https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376
题目的大意是
输入一群城市之间(0~n-1)的路径和该城市拥有的救援队数目,再给与你起点城市的编号和终点城市的编号, 请输出起点到终点城市的最短路径有几条,和最短路径上能收集的最大救援队的数目 输入格式 第一行4个数 n m s e. n表示城市的个数(0~n-1) , m表示城市之间的路径 , s表示起点城市的编号, e表示终点城市的编号 第二行 有n个数字 表示每个城市拥有的救援队数目 下面是m行 每行三个数字 a b l. a表示一个城市编号 b表示一个城市编号 l表示两城市之间的距离(道路是双向的) 输出格式 输出两个 数字 j k. j表示最短路径有多少条 k表示能收集的最大救援队数目 用空格隔开 示例 Sample Input: 5 6 0 2 1 2 1 5 3 0 1 1 0 2 2 0 3 1 1 2 1 2 4 1 3 4 1 Sample Output: 2 4
解答
考虑到数据范围不大 基本都在几百以内,可以直接DFS加上剪枝即可搞定
想进一步深入学习的同学可以考虑学习图论算法
使用DFS 尝试从0点出发 到终点2的各种走法,不断更新每个城市从0点出发能够达到的最短路径。
如果当前达到X点的走法的路径比之前到达X点的走法的路径要长,那么这种走法就不需要继续尝试了,因为按照这种走法达到后面的点肯定不是最短路径(剪枝)
if (currDis > dist[x]){return;}
如果当前达到X点的走法的路径比之前到达X点的走法的路径相等,
那么就需要记录达到该点的最短路径的个数,
path[x]++;
同时还需要更新下能收集到救援队数目
sum[x] = max(currSum,sum[x] );
#include <iostream> #include <vector> #include <algorithm> #include <memory.h> using namespace std; const int N = 700; const int INF = 0x3f3f3f3f; int graph[N][N]; int teams[N]; int start = -1; int endp = -1; int n, m; int path[N]; int dist[N]; int sum[N]; void dfs(int curr,int currDis, int currPath, int currSum) { //剪枝 当前走法走到curr点已经不可能更短了 if (currDis > dist[curr]){return;} if (currDis < dist[curr]) { dist[curr] = currDis; sum[curr] = currSum; path[curr] = 1; } else if (currDis == dist[curr] ) { sum[curr] = max(currSum,sum[curr] ); path[curr]++; } if (curr == endp) { return; } for (int i = 0; i < n; i++) { if (i != curr && graph[curr][i] != INF) { //currPath++; currSum += teams[i]; currDis += graph[curr][i]; dfs(i, currDis,currPath, currSum); //currPath--; currSum-= teams[i]; currDis -= graph[curr][i]; } } return; } int main() { //接受输入 得到 城市的个数和路径的个数 已经起点城市和终点城市 cin >> n >> m >> start >> endp; //得到输入的每个城市的救援队数目 for (int i = 0; i < n; i++) { cin >> teams[i]; } //初始化 图所有路径为最大值0x3f3f3f3f memset(graph,0x3f,sizeof(graph)); memset(dist, 0x3f, sizeof dist); //得到两个城市之间的路径 for (int i = 0; i < m; i++) { int a, b, l; cin >> a >> b >> l; graph[a][b] = min(graph[a][b],l); graph[b][a] = min(graph[b][a], l); } dfs(start,0,0, teams[start]); cout << path[endp] << " " << sum[endp] << endl; return 0; }
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话