题目分析:

本题我有两种思路,一种是只依靠dijkstra算法,在dijkstra部分直接判断所有的情况,以局部最优解得到全局最优解,另一种是dijkstra + dfs,先计算出最短距离以及每个点的可能前驱点,然后用dfs搜索每一条道路对最优路径进行维护,并且第二种方法记录道路的方式比较巧妙值得学习掌握(在dfs部分用一条临时路径进行维护)

对于字符串如何以整数的形式存储到二维数组中,这里用的是map的方式,当然也可以通过字符串计算出hash值去索引,毕竟是三个大写字母的字符串

本题代码:

  1 #include<iostream>
2 #include<string>
3 #include<cmath>
4 #include<map>
5 #include<string.h>
6 #include<vector>
7 #include<algorithm>
8 #include<stdio.h>
9 using namespace std;
10
11 const int M = 0x3f3f3f3f;
12 const int N = 205;
13 int mat[N][N];
14 int vis[N];
15 int dist[N];
16 int peo[N];
17 vector<int> pre[N];
18 vector<int> path, temppath;
19 map<string, int> mp1; //每个城市对应的id
20 map<int, string> mp2; //每个id对应的城市
21 int n, m, min_dist, max_kill, road_num;
22 string from, to;
23
24 int minn(){
25 int k = -1;
26 int Min = M;
27 for(int i = 1; i <= n; i++){
28 if(vis[i] == 0 && dist[i] < Min){
29 Min = dist[i];
30 k = i;
31 }
32 }
33 return k;
34 }
35
36 void dijkstra(){
37 max_kill = 0;
38 road_num = 0;
39 min_dist = 0;
40 memset(vis, 0, sizeof(vis));
41 memset(dist, M, sizeof(dist));
42 dist[1] = 0; //起点到自己距离为0
43 for(int i = 1; i <= n; i++){
44 int k = minn();
45 if(k == -1) break;
46 vis[k] = 1;
47 for(int j = 1; j <= n; j++){
48 if(vis[j] == 0 && dist[k] + mat[k][j] < dist[j]){
49 dist[j] = dist[k] + mat[k][j];
50 pre[j].clear();
51 pre[j].push_back(k);
52 }else if(vis[j] == 0 && dist[k] + mat[k][j] == dist[j]){
53 pre[j].push_back(k);
54 }
55 }
56 }
57 min_dist = dist[mp1[to]];
58 }
59
60 void dfs(int x){
61 temppath.push_back(x);
62 if(x == mp1[from]){
63 //现在需要找出同距离下点最多且杀敌最多
64 road_num++; //不论是点多的 少的 一样多的都算是同样距离的一条最短路径
65 int kill = 0;
66 for(int i = temppath.size()-1; i >= 0; i--){
67 int id = temppath[i];
68 kill += peo[id];
69 }
70 if(temppath.size() > path.size()){
71 path = temppath;
72 max_kill = kill;
73 }else if(temppath.size() == path.size()){
74 if(kill > max_kill){
75 max_kill = kill;
76 path = temppath;
77 }
78 }
79 temppath.pop_back();
80 return;
81 }
82 for(int i = 0; i < pre[x].size(); i++)
83 dfs(pre[x][i]);
84 temppath.pop_back();
85 }
86
87 int main(){
88 scanf("%d%d", &n, &m);
89 cin>>from>>to;
90 mp1[from] = 1;
91 mp2[1] = from;
92 for(int i = 2; i <= n; i++){
93 string s; int x;
94 cin>>s; scanf("%d", &x);
95 mp1[s] = i;
96 mp2[i] = s;
97 peo[mp1[s]] = x;
98 }
99 memset(mat, M, sizeof(mat));
100 for(int i = 1; i <= m; i++){
101 string s1, s2;
102 cin>>s1>>s2;
103 scanf("%d", &mat[mp1[s1]][mp1[s2]]);
104 mat[mp1[s2]][mp1[s1]] = mat[mp1[s1]][mp1[s2]];
105 }
106 dijkstra(); //计算出最短路径
107 dfs(mp1[to]); //计算最优路径
108 cout<<mp2[1];
109 for(int i = path.size()-2; i >= 0; i--) cout<<"->"<<mp2[path[i]]; //注意起始点已经输出了
110 printf("\n");
111 printf("%d %d %d\n", road_num, min_dist, max_kill);
112 return 0;
113 }

天梯赛练习 L3-011 直捣黄龙 (30分) dijkstra + dfs的更多相关文章

  1. 天梯赛练习 L3-008 喊山 (30分) bfs搜索

    题目分析: 本题是一题比较简单的bfs搜索题,首先由于数据给的比较多不能直接开二维数组存放,而是用了vector的动态的二维数组的形式存放,对于每个出发点,我们bfs向四周搜索,标记搜索过的点,遇到搜 ...

  2. PAT天梯赛练习 L3-004 肿瘤诊断 (30分) 三维BFS

    题目分析: 可能是我的理解能力比较差,在读题的时候一直以为所有的切片是可以排列组合的,并不是按照输入顺序就定死的,那么这题就变得十分的复杂啦~~~~~,查看的题解之后发现所有的切片并没有所谓的自由组合 ...

  3. L3-007 天梯地图 (30 分) dijkstra

    本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线:一条是最短距离的路线.题目保证对任意的查询请求,地图上都至少存在一条可达路线. 输 ...

  4. PAT 甲级 1053 Path of Equal Weight (30 分)(dfs,vector内元素排序,有一小坑点)

    1053 Path of Equal Weight (30 分)   Given a non-empty tree with root R, and with weight W​i​​ assigne ...

  5. 天梯赛练习 L3-007 天梯地图 (30分) Dijkstra

    题目分析: 本题的题意比较清晰,就是有一个起点和一个终点,给出m条路径,可能是单向的可能是双向的,同时一条路有两个权重,分别是通过这条路需要的时间和这条路的路径长度,题目需要求出两条路径,一条是在最快 ...

  6. 团体程序设计天梯赛L3-019 代码排版(23分)

    打算学完编译原理后再次实现它... 以下为比较“杂乱”的方法: 海量数据: https://pan.baidu.com/s/1Prd0ZqNLoCLLvXyJjCef3w 如果大家有发现这个程序的问题 ...

  7. 【PAT甲级】1053 Path of Equal Weight (30 分)(DFS)

    题意: 输入三个正整数N,M,S(N<=100,M<N,S<=2^30)分别代表数的结点个数,非叶子结点个数和需要查询的值,接下来输入N个正整数(<1000)代表每个结点的权重 ...

  8. 1034 Head of a Gang (30分)(dfs 利用map)

    One way that the police finds the head of a gang is to check people's phone calls. If there is a pho ...

  9. PAT A1103 Integer Factorization (30 分)——dfs,递归

    The K−P factorization of a positive integer N is to write N as the sum of the P-th power of K positi ...

随机推荐

  1. JApiDocs(自动生成接口文档神器)

    JApiDocs教程 前言 作为一名优秀的程序员来说,由于涉及到要与前端进行对接,所以避免不了的就是写接口文档.写完接口文档,一旦代码返回结果,参数等出现变动,接口文档还得随之改动,十分麻烦,违背了我 ...

  2. js实现弹幕

    弹幕是一个很常见的功能,下面是本人封装的一个小小的实现方案,存在不足之处可以提出来或自由改进. 直接上代码:复制可运行 <!DOCTYPE html> <html> <h ...

  3. GaussDB(DWS)应用实践丨负载管理与作业排队处理方法

    摘要:本文用来总结一些GaussDB(DWS)在实际应用过程中,可能出现的各种作业排队的情况,以及出现排队时,我们应该怎么去判断是否正常,调整一些参数,让资源分配与负载管理更符合当前的业务:或者在作业 ...

  4. mysql数据库设置超时断开连接

    mysql数据库长时间未操作自动断开连接由参数:interactive_timeout和wait_timeout控制,默认都是8小时(28800分钟) mysql> show variables ...

  5. 【面试专栏】JAVA锁机制

    1. 悲观锁 / 乐观锁   在Java和数据库中都存在悲观锁和乐观锁的应用.Mysql锁机制中的悲观锁和乐观锁请查看:   Mysql锁机制--悲观锁和乐观锁   悲观锁:在获得数据时先加锁,只到数 ...

  6. C# 9.0中引入的新特性init和record的使用思考

    写在前面 .NET 5.0已经发布,C# 9.0也为我们带来了许多新特性,其中最让我印象深刻的就是init和record type,很多文章已经把这两个新特性讨论的差不多了,本文不再详细讨论,而是通过 ...

  7. rancher安装,快速安装

    apt-get install docker.io docker -y docker run -d --restart=always -v /data/rancher_server:/var/lib/ ...

  8. vue-router 路由传参的几种方式,刷新页面参数丢失

    常见场景:点击列表详情,跳转到详情内页,传递id参数获取详情数据. 我们先来看看路由跳转的几种方式: 1.通过params方式传参 通过$route.push的path携带参数方式 // 路由配置 { ...

  9. 个人博客搭建Python实现-尝试-遇到的问题(10.1.1)

    @ 目录 前提 1.Git相关 2.环境相关 3.nginx相关 4.linux相关 关于作者 前提 自己搭建了一个简单的flask微信公众号 在github上找到一个django搭建的博客网站 有一 ...

  10. Centos7__Scrapy + Scrapy_redis 用Docker 实现分布式爬虫

    原理:其实就是用到redis的优点及特性,好处自己查--- 1,scrapy 分布式爬虫配置: settings.py BOT_NAME = 'first' SPIDER_MODULES = ['fi ...