1087. All Roads Lead to Rome (30)[dijkstra/dfs回溯剪枝]

2023-12-02 15:58

本文主要是介绍1087. All Roads Lead to Rome (30)[dijkstra/dfs回溯剪枝],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 原题: https://www.patest.cn/contests/pat-a-practise/1087

2. 思路:

题意:
单源最短路问题,同时要输出路径。
思路:
可以用dijkstra,用path记录路径。
也可以dfs,回溯剪枝。
或者两者结合,dijkstra找出最短路长度,再dfs.
我用的第一种方法。
已AC。

3. 源码:

#include<iostream>
#include<map>
#include<string>
using namespace std;const int Max = 200 + 5;//最大结点数
const int INF = 0x7FFFFFFF;//表示无穷大
int G[Max][Max];//图的邻接矩阵表示法
int collect[Max] = { 0 };//记录某点是否被收录
int path[Max];//存储最短路径上的结点号
int dist[Max];//到某点的最短路径长度
int happy[Max] = { 0 };//记录每个点的幸福指数
int sum_happy[Max] = { 0 };//最短路径上的总指数
int route[Max] = { 0 };//到某点的路径条数
int cnt[Max] = { 0 };//记录到某点的路径上的点数,不含起点
int N, K;//分别为结点数, 路径数
map<string, int> id;//字符串映射成数字
map<int, string> name;//数字映射成字符串int findMin();//找出未收录的最小权值
void dijkstra(int start);//dijkstra经典算法
void print(int num);//递归逆序打印路径int main(void)
{//freopen("in.txt", "r", stdin);string s, d;//起点,终点cin >> N >> K >> s;id[s] = 0;//起点映射为0name[0] = s;for (int i = 0; i < N; i++)//图的初始化{for (int j = 0; j < N; j++)G[i][j] = INF;path[i] = -1;}for (int i = 1; i < N; i++)//读入数据{int val;//幸福指数cin >> s >> val;id[s] = i;name[i] = s;happy[i] = val;}for (int i = 0; i < K; i++){int wgt;//权值cin >> s >> d >> wgt;int s1, d1;s1 = id[s];d1 = id[d];G[s1][d1] = G[d1][s1] = wgt;}dijkstra(0);//最短路经典算法int end = id["ROM"];//终点printf("%d %d %d %d\n", route[end], dist[end], sum_happy[end],sum_happy[end] / (cnt[end] + 1));//分别为最短路的路径数, 路径长度,总指数,平均指数print(end);//打印路径cout << endl;return 0;
}int findMin()//找出未收录的最小权值
{int min_id = -1;int min_val = INF;for (int i = 0; i < N; i++){if (collect[i] == 0 && dist[i] < min_val){min_val = dist[i];min_id = i;}}return min_id;
}void dijkstra(int start)//dijkstra经典算法
{for (int i = 0; i < N; i++)//初始化{dist[i] = G[start][i];sum_happy[i] = happy[i];}route[start] = 1;//起点的路径条数初始为1, 0不可以。dist[start] = 0;//起点到起点为0while (1){int v = findMin();if (v == -1)//循环终止break;collect[v] = 1;for (int w = 0; w < N; w++){if (collect[w] == 0 && G[v][w] < INF){if ((dist[v] + G[v][w]) < dist[w])//找到最短路{cnt[w] = cnt[v] + 1;//到w的路径上的结点数加1dist[w] = dist[v] + G[v][w];route[w] = route[v];//更新路径条数sum_happy[w] = sum_happy[v] + happy[w];path[w] = v;//表示到w的上一个结点是v}else if ((dist[v] + G[v][w]) == dist[w])//存在多个最短路{route[w] += route[v];//更新路径条数if (sum_happy[w] < (sum_happy[v] + happy[w]))//存在最大幸福指数的路径{path[w] = v;cnt[w] = cnt[v] + 1;sum_happy[w] = sum_happy[v] + happy[w];}else if ((sum_happy[w] == sum_happy[v] + happy[w])&& (cnt[w] > (cnt[v] + 1)))//存在最大的平均指数的路径{path[w] = v;cnt[w] = cnt[v] + 1;}}}	}}return;
}void print(int num)//递归逆序打印路径
{if (num == -1)//递归结束条件{cout << name[0];return;}print(path[num]);cout << "->" << name[num];
}


这篇关于1087. All Roads Lead to Rome (30)[dijkstra/dfs回溯剪枝]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/445926

相关文章

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

30常用 Maven 命令

Maven 是一个强大的项目管理和构建工具,它广泛用于 Java 项目的依赖管理、构建流程和插件集成。Maven 的命令行工具提供了大量的命令来帮助开发人员管理项目的生命周期、依赖和插件。以下是 常用 Maven 命令的使用场景及其详细解释。 1. mvn clean 使用场景:清理项目的生成目录,通常用于删除项目中自动生成的文件(如 target/ 目录)。共性规律:清理操作

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问

uva 10801(乘电梯dijkstra)

题意: 给几个电梯,电梯0 ~ n-1分别可以到达很多层楼。 换乘电梯需要60s时间。 问从0层到target层最小的时间。 解析: 将进入第0层的电梯60s也算上,最后减。 坑点是如果target为0输出0。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algori

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

poj 3255 次短路(第k短路) A* + spfa 或 dijkstra

题意: 给一张无向图,求从1到n的次短路。 解析: A* + spfa 或者 dijkstra。 详解见上一题:http://blog.csdn.net/u013508213/article/details/46400189 本题,spfa中,stack超时,queue的效率最高,priority_queue次之。 代码: #include <iostream>#i

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

hdu1010 奇偶剪枝

恰好t时间到达 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.Arrays;import