13 #define INFINITY 10000
15 vector<string> places;
16 set<string> places_set;
17 map<pair<string, string>, int> sparse_dist;
21 void check_name_inserted(char* name)
23 if (places_set.count(name) == 0) {
24 places_set.insert(name);
25 places.push_back(name);
31 int num_places = places.size();
32 dist = new int[num_places * num_places];
34 for (int i = 0; i < num_places; ++i) {
35 dist[i * num_places + i] = 0;
38 for (int i = 0; i < num_places; ++i) {
39 for (int j = i + 1; j < num_places; ++j) {
42 pair<string, string> comb = make_pair(places[i], places[j]);
43 if (sparse_dist.count(comb) != 0) {
44 d = sparse_dist[comb];
46 comb = make_pair(places[j], places[i]);
47 if (sparse_dist.count(comb) != 0) {
48 d = sparse_dist[comb];
50 dist[i * num_places + j] = d;
51 dist[j * num_places + i] = d;
58 int num_places = places.size();
59 for (int i = 0; i < num_places; ++i) {
60 printf("%d: %s\n", i, places[i].c_str());
62 for (int i = 0; i < num_places; ++i) {
63 for (int j = 0; j < num_places; ++j) {
64 printf("%5d ", dist[i * num_places + j]);
72 int num_places = places.size();
74 for (int k = 0; k < num_places; ++k) {
75 for (int i = 0; i < num_places; ++i) {
76 for (int j = 0; j < num_places; ++j) {
77 dist[i * num_places + j] =
78 min(dist[i * num_places + j],
79 dist[i * num_places + k] + dist[k * num_places + j]);
92 int num_places = places.size();
93 cache_size = (1 << num_places);
94 cache = new int[cache_size * num_places];
96 for (int i = 0; i < cache_size * num_places; ++i) {
100 best_cost = INFINITY;
101 finish_mask = (1 << num_places) - 1;
104 int tsp(int node_num, int visited_mask, int cost_so_far)
106 int num_places = places.size();
107 if (cache[node_num * cache_size + visited_mask] != -1) {
108 return cache[node_num * cache_size + visited_mask];
110 if (cost_so_far > best_cost) {
114 if (visited_mask == finish_mask) {
117 cost_so_far += dist[node_num * num_places + 0];
118 cache[node_num * cache_size + visited_mask] = dist[node_num * num_places + 0];
119 if (cost_so_far < best_cost) {
120 best_cost = cost_so_far;
122 return dist[node_num * num_places + 0]; */
125 int best_this_cost = INFINITY;
126 for (int i = 0; i < num_places; ++i) {
127 if (visited_mask & (1 << i)) {
131 int cost = dist[node_num * num_places + i]
132 + tsp(i, visited_mask | (1 << i), cost_so_far + dist[node_num * num_places + i]);
133 if (cost < best_this_cost) {
134 best_this_cost = cost;
138 cache[node_num * cache_size + visited_mask] = best_this_cost;
139 return best_this_cost;
142 void backtrack(int node_num, int visited_mask)
144 int num_places = places.size();
145 if (visited_mask == finish_mask) {
150 int best_this_cost = INFINITY;
151 for (int i = 0; i < num_places; ++i) {
152 if (visited_mask & (1 << i)) {
156 int cost = dist[node_num * num_places + i] +
157 cache[i * cache_size + (visited_mask | (1 << i))];
159 if (cost < best_this_cost) {
161 best_this_cost = cost;
165 printf("%s [%d] [%d to %d costs %d]\n", places[best_node].c_str(), best_this_cost, node_num, best_node, dist[node_num * num_places + best_node]);
166 backtrack(best_node, visited_mask | (1 << best_node));
176 if (scanf("%s %s %d", name1, name2, &dist) != 3) {
180 check_name_inserted(name1);
181 check_name_inserted(name2);
182 sparse_dist.insert(make_pair(make_pair(name1, name2), dist));
193 printf("fg [%d]\n", best_cost);