1 #include <cstdio> 2 #include <climits> 3 #include <iostream> 4 #include <vector> 5 #include <string> 6 #include <queue> 7 #include <unordered_map> 8 #include <algorithm> 9 10 using namespace std; 11 12 typedef pair<int, int> P; 13 14 class City { 15 public: 16 int id; 17 string name; 18 int happiness; 19 int distance; 20 vector<int> adj; 21 City(string _name, int _happiness = 0, int _id = 0, int _distance = INT_MAX) : 22 name(_name), happiness(_happiness), id(_id), distance(_distance) {} 23 }; 24 25 class Solution { 26 public: 27 int happiness; 28 vector<int> path; 29 Solution(int happy = 0) : happiness(happy) {} 30 }; 31 32 bool solution_cmp_inv(const Solution& a, const Solution& b) { 33 if (a.happiness > b.happiness) { 34 return true; 35 } else if (a.happiness < b.happiness) { 36 return false; 37 } else { 38 return a.happiness / a.path.size() > b.happiness / b.path.size(); 39 } 40 } 41 42 int G[200][200]; 43 44 vector<Solution> res; 45 46 void build_solution(vector<City*> &cities, Solution &s, int pos, int dst, int hap) { 47 // we know that start city index must be zero 48 // so when pos == 0, we get a solution 49 if (pos == 0) { 50 res.push_back(s); 51 res.back().happiness= hap; 52 return; 53 } 54 55 // we are now at the cities[pos] with left dst to the start city 56 City* city = cities[pos]; 57 for (int i=0; i<city->adj.size(); i++) { 58 City* adj = cities[city->adj[i]]; 59 60 // we could not go to this adj city, not on the shortest path 61 if (adj->distance + G[pos][adj->id] != dst) { 62 continue; 63 } 64 65 // here we can assume that the adj city is on the shortest path 66 s.path.push_back(adj->id); 67 build_solution(cities, s, adj->id, adj->distance, hap + adj->happiness); 68 s.path.pop_back(); 69 } 70 } 71 int main() { 72 vector<City*> cities; 73 74 unordered_map<string, int> city_lookup; 75 76 int N, K; 77 char buf[10], buf2[10]; 78 79 scanf("%d%d%s", &N, &K, buf); 80 81 City* start = new City(buf, 0, 0, 0); 82 cities.push_back(start); 83 city_lookup.insert(make_pair(start->name, 0)); 84 85 int tmp = 0; 86 for (int i=1; i<N; i++) { 87 scanf("%s%d", buf, &tmp); 88 cities.push_back(new City(buf, tmp, cities.size())); 89 city_lookup.insert(make_pair(buf, cities.back()->id)); 90 } 91 92 tmp = 0; 93 int ca = 0, cb = 0; 94 95 for (int i=0; i<K; i++) { 96 scanf("%s%s%d", buf, buf2, &tmp); 97 98 ca = city_lookup.find(buf)->second; 99 cb = city_lookup.find(buf2)->second; 100 101 cities[ca]->adj.push_back(cb); 102 cities[cb]->adj.push_back(ca); 103 104 G[ca][cb] = G[cb][ca] =tmp; 105 } 106 107 priority_queue<P, vector<P>, greater<P>> cand_cities; 108 cand_cities.push(make_pair(0, 0)); 109 110 while(!cand_cities.empty()) { 111 P p = cand_cities.top(); 112 cand_cities.pop(); 113 114 City* sel_city = cities[p.second]; 115 116 if (sel_city->distance < p.first) continue; 117 118 for (int i=0; i<sel_city->adj.size(); i++) { 119 City* adj_city = cities[sel_city->adj[i]]; 120 121 int new_dst = sel_city->distance + G[sel_city->id][adj_city->id]; 122 123 if (adj_city->distance > new_dst) { 124 adj_city->distance = new_dst; 125 cand_cities.push(make_pair(new_dst, adj_city->id)); 126 } 127 } 128 } 129 130 City* rom = cities[city_lookup.find("ROM")->second]; 131 132 Solution s; 133 134 build_solution(cities, s, rom->id, rom->distance, rom->happiness); 135 136 sort(res.begin(), res.end(), solution_cmp_inv); 137 138 Solution& best = res[0]; 139 140 printf("%d %d %d %d ", res.size(), rom->distance, best.happiness, best.happiness / best.path.size()); 141 142 for (int i = best.path.size() - 1; i>=0; i--) { 143 printf("%s->", cities[best.path[i]]->name.c_str()); 144 } 145 printf("ROM "); 146 return 0; 147 }
稍微有点烦, 不过思路比较简单,还是跟课本靠的比较近最短路径,然后再dfs扫出所有可能路径, 进行一个排序就ok了,感谢STL,用单纯的C写的话...