题目分析:

这题我在写的时候在PTA提交能过但是在牛客网就WA了一个点,先写一下思路留个坑

这题的简单来说就是需要找一条最短路->最开心->点最少(平均幸福指数自然就高了),由于本题给出的所有的城市的名称都是字符串(三个大写字母),所以我先将每个字符串计算一个hash值去代表每一个城市,接着就是用dijkstra算法去逐步判断各种情况,是直接用了一个dijkstra去计算,而没有说是先dijkstra算出最短距离再dfs所有的路径去找出最优解,因为我觉得这题局部最优就能反映到全局最优,也不知是不是想错了才在牛客上有一个点过不去QAQ...

本题代码:

  1 #include<iostream>
2 #include<vector>
3 #include<stdio.h>
4 #include<string.h>
5 #include<cmath>
6 #include<string>
7 #include<algorithm>
8 #include<map>
9 using namespace std;
10
11 const int N = 3000;
12 const int M = 0x3f3f3f3f;
13 int mat[N][N];
14 int dist[N];
15 int vis[N];
16 int hap[N];
17 int get_hap[N]; //已知情况下到i点能获得的幸福值
18 int way[N]; //到达每个点有多少种走法
19 int num[N]; //到达i点需要走多少个点 第一个sta不算
20 vector<int> v[N];
21 int pre[N];
22 map<int, string> mp;
23 int n, m, min_dist, max_hap;
24
25 int trans(string s){
26 int len = s.size();
27 int sum = 0;
28 for(int i = 0; i < len; i++){
29 sum = sum * 10 + s[i] - 'A';
30 }
31 return sum;
32 }
33
34 int minn(){
35 int Min = M;
36 int k = -1;
37 for(int i = 0; i < 3000; i++){
38 if(vis[i] == 0 && dist[i] < Min){
39 Min = dist[i];
40 k = i;
41 }
42 }
43 return k;
44 }
45
46 void out(int x){
47 if(pre[x] == -1){
48 cout<<mp[x];
49 return;
50 }else{
51 out(pre[x]);
52 cout<<"->"<<mp[x];
53 return;
54 }
55 }
56
57 void dijkstra(int st){
58 memset(dist, M, sizeof(dist));
59 for(int i = 0; i < v[st].size(); i++) dist[v[st][i]] = mat[st][v[st][i]];
60 dist[st] = 0; //保证自己先选自己
61 way[st] = 1; //到自己有一条路
62 pre[st] = -1;
63 for(int i = 1; i <= n; i++){
64 int k = minn();
65 if(k == -1) break;
66 vis[k] = 1;
67 for(int j = 0; j < 3000; j++){
68 if(vis[j] == 0 && dist[k] + mat[k][j] < dist[j]){
69 dist[j] = dist[k] + mat[k][j];
70 get_hap[j] = hap[j] + get_hap[k];
71 pre[j] = k;
72 way[j] = way[k];
73 num[j] = num[k] + 1;
74 }else if(vis[j] == 0 && dist[k] + mat[k][j] == dist[j]){
75 way[j] = way[j] + way[k];
76 if(get_hap[k] + hap[j] > get_hap[j]){ //距离相同但是更快乐
77 get_hap[j] = get_hap[k] + hap[j];
78 pre[j] = k;
79 num[j] = num[k] + 1;
80 }else if(get_hap[k] + hap[j] == get_hap[j]){//距离相同且同样快乐则比较点的个数
81 if(num[k] + 1 < num[j]){ //点更少
82 pre[j] = k;
83 num[j] = num[k] + 1;
84 }
85 }
86 }
87 }
88 }
89 int en = trans("ROM");
90 printf("%d %d %d %d\n", way[en], dist[en], get_hap[en], get_hap[en]/num[en]);
91 out(en);
92 printf("\n");
93 }
94
95 int main(){
96 scanf("%d%d", &n, &m);
97 string sta;
98 cin>>sta;
99 int st = trans(sta);
100 mp[st] = sta;
101 memset(vis, 0, sizeof(vis));
102 memset(hap, 0, sizeof(hap));
103 memset(mat, M, sizeof(mat));
104 memset(num, 0, sizeof(num));
105 memset(get_hap, 0, sizeof(get_hap));
106 memset(way, 0, sizeof(way));
107 for(int i = 1; i < n; i++){
108 string s;
109 cin>>s;
110 int tt = trans(s);
111 mp[tt] = s;
112 int x;
113 scanf("%d", &x);
114 hap[tt] = x; //根据hash值锁定幸福值
115 }
116 for(int i = 1; i <= m; i++){
117 string s1, s2; int x;
118 cin>>s1>>s2; scanf("%d", &x);
119 int t1 = trans(s1);
120 int t2 = trans(s2);
121 v[t1].push_back(t2);
122 v[t2].push_back(t1);
123 mat[t1][t2] = x;
124 mat[t2][t1] = x;
125 }
126 dijkstra(st);
127 return 0;
128 }

PAT甲级练习 1087 All Roads Lead to Rome (30分) 字符串hash + dijkstra的更多相关文章

  1. 【PAT甲级】1087 All Roads Lead to Rome (30 分)(dijkstra+dfs或dijkstra+记录路径)

    题意: 输入两个正整数N和K(2<=N<=200),代表城市的数量和道路的数量.接着输入起点城市的名称(所有城市的名字均用三个大写字母表示),接着输入N-1行每行包括一个城市的名字和到达该 ...

  2. PAT (Advanced Level) 1087. All Roads Lead to Rome (30)

    暴力DFS. #include<cstdio> #include<cstring> #include<cmath> #include<vector> # ...

  3. [图的遍历&多标准] 1087. All Roads Lead to Rome (30)

    1087. All Roads Lead to Rome (30) Indeed there are many different tourist routes from our city to Ro ...

  4. 1087. All Roads Lead to Rome (30)

    时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Indeed there are many different ...

  5. 1087 All Roads Lead to Rome (30)(30 分)

    Indeed there are many different tourist routes from our city to Rome. You are supposed to find your ...

  6. PAT 1087 All Roads Lead to Rome[图论][迪杰斯特拉+dfs]

    1087 All Roads Lead to Rome (30)(30 分) Indeed there are many different tourist routes from our city ...

  7. pat1087. All Roads Lead to Rome (30)

    1087. All Roads Lead to Rome (30) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yu ...

  8. PAT甲级1087. All Roads Lead to Rome

    PAT甲级1087. All Roads Lead to Rome 题意: 确实有从我们这个城市到罗马的不同的旅游线路.您应该以最低的成本找到您的客户的路线,同时获得最大的幸福. 输入规格: 每个输入 ...

  9. PAT 1087 All Roads Lead to Rome

    PAT 1087 All Roads Lead to Rome 题目: Indeed there are many different tourist routes from our city to ...

随机推荐

  1. libev的用法

    本例是以linux环境c++的用法,ide用的是vs2019 一.libev的安装 我们采用的是apt-get方法(偷懒^_^),你也可以采用源码方式安装 sudo apt-get install l ...

  2. Jmeter(2)基础知识

    一.Jmeter测试计划 1.测试计划用来描述一个性能/接口测试的脚本和场景设计 独立运行每个线程组:用于控制测试计划中的多个线程组的执行顺序.不勾选时,默认各线程组并行.随机执行. 主线程结束后运行 ...

  3. Bootstrap 的基本使用

    一.Bootstrap简介 Bootstrap 是目前受欢迎的前端框架之一,是基于HTML,CSS,JavaScript的,它简洁灵活,使web开发更加快捷 中文官网:http://www.bootc ...

  4. Java基础语法吐血整理

    前言 自己的Java理论知识方面一直都不是很好,决定从0开始好好总结下,把想到的和以前不确定的(查阅资料确定)的知识整理一下,加油!!坚持!!! Java概述 Java三大体系 1.JavaSE 标准 ...

  5. 日期格式化:推荐使用SimpleDateFormat

    一.主题 日期格式化成字符串:SimpleDateFormat > DateFormatUtils 二.code public void DateFormat(){ SimpleDateForm ...

  6. Flink开发中的问题

    1. 流与批处理的区别 流处理系统 流处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,然后立刻通过网络传输到下一个节点,由下一个节点继续处理. 批处理系统 批处理系统, ...

  7. Linux系列之makefile的简单入门

    什么是makefile呢? 一个工程中的源文件不计其数,其按类型.功能.模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译, ...

  8. Helm 带你飞

    文章目录 目录 文章目录 在没使用 Helm之前,向 K8S部署应用,我们要依次部署 deployment. svc 等,步骤较繁琐.况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复 ...

  9. 简单谈谈contextlib的使用

    简单谈谈contextlib的使用 写在前面 做这件事的原因: 在看书的时候,我发现了有大佬们用contextlib管理上下文,真的很牛皮,但是百度了以下,每个大佬都写了很多很全很深刻,讲道理五花八门 ...

  10. ucore操作系统学习(七) ucore lab7同步互斥

    1. ucore lab7介绍 ucore在前面的实验中实现了进程/线程机制,并在lab6中实现了抢占式的线程调度机制.基于中断的抢占式线程调度机制使得线程在执行的过程中随时可能被操作系统打断,被阻塞 ...