PAT甲级练习 1087 All Roads Lead to Rome (30分) 字符串hash + dijkstra

题目分析:

这题我在写的时候在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
", way[en], dist[en], get_hap[en], get_hap[en]/num[en]); 
 91     out(en);
 92     printf("
");
 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 } 
原文地址:https://www.cnblogs.com/YLTFY1998/p/12266262.html