#include <stdio.h> #include <vector> #include <queue> #include <utility> #include <string.h> #include <algorithm> using namespace std; #define MAX_NODES 100000 #define MAX_EDGES 100000 #define MAX_NODES_TO_VISIT 10 const int INF = 2147483647; typedef pair<int, int> PII; class Dijkstra { private: int N; vector<vector<PII> > edges; vector<int> dist, dad; public: Dijkstra(int number_of_nodes) { N = number_of_nodes; edges = vector<vector<PII> >(N); } void addEdge(int from, int to, int weight) { edges[from].push_back(make_pair(weight, to)); } void run(int start_node) { // use priority queue in which top element has the "smallest" priority priority_queue<PII, vector<PII>, greater<PII> > Q; dist = vector<int>(N, INF); dad = vector<int>(N, -1); Q.push(make_pair(0, start_node)); dist[start_node] = 0; while (!Q.empty()) { PII p = Q.top(); //if (p.second == end_node) //break; Q.pop(); int here = p.second; for (vector<PII>::iterator it = edges[here].begin(); it != edges[here].end(); it++) { if (dist[here] + it->first < dist[it->second]) { dist[it->second] = dist[here] + it->first; dad[it->second] = here; Q.push(make_pair(dist[it->second], it->second)); } } }; } int getDistanceTo(int end_node) { return dist[end_node]; } vector<int> getPathTo(int end_node) { vector<int> path; for (int i = end_node; i != -1; i = dad[i]) path.push_back(i); reverse(path.begin(), path.end()); return path; } }; int node_to_visit[MAX_NODES_TO_VISIT]; int main() { int cases; for (scanf("%d", &cases); cases; cases--) { int number_of_nodes, number_of_edges; scanf("%d%d", &number_of_nodes, &number_of_edges); Dijkstra dijkstra = Dijkstra(number_of_nodes); for (int i = 0; i < number_of_edges; i++) { int from, to, weight; scanf("%d%d%d", &from, &to, &weight); dijkstra.addEdge(from, to, weight); dijkstra.addEdge(to, from, weight); } int number_of_nodes_to_visit; scanf("%d", &number_of_nodes_to_visit); for (int i = 0; i < number_of_nodes_to_visit; i++) scanf("%d", &node_to_visit[i]); int distance[MAX_NODES_TO_VISIT][MAX_NODES_TO_VISIT]; distance[0][0] = 0; for (int i = 1; i < number_of_nodes_to_visit; i++) { dijkstra.run(node_to_visit[i]); for (int j = 0; j < i; j++) { distance[i][j] = dijkstra.getDistanceTo(node_to_visit[j]); distance[j][i] = dijkstra.getDistanceTo(node_to_visit[j]); } distance[i][i] = 0; } int T[1 << MAX_NODES_TO_VISIT][MAX_NODES_TO_VISIT]; memset(T, 127, sizeof(T)); int final_mask = (1 << number_of_nodes_to_visit) - 1; dijkstra.run(0); typedef pair<int, pair<int, int> > PIII; priority_queue<PIII, vector<PIII>, greater<PIII> > q; for (int i = 0; i < number_of_nodes_to_visit; i++) { T[1 << i][i] = dijkstra.getDistanceTo(node_to_visit[i]); q.push(make_pair(T[1 << i][i], make_pair(1 << i, i))); } int sol = INF, finals_count = number_of_nodes_to_visit; while (!q.empty()) { PIII now = q.top(); PII state = now.second; if (state.first == final_mask) { if (now.first + T[1 << state.second][state.second] < sol) sol = now.first + T[1 << state.second][state.second]; if (--finals_count == 0) break; } q.pop(); for (int i = 0; i < number_of_nodes_to_visit; i++) { int new_mask = state.first | (1 << i); int new_cost = T[state.first][state.second] + distance[state.second][i]; if (new_mask != state.first && new_cost < T[new_mask][i]) { T[new_mask][i] = new_cost; q.push(make_pair(new_cost, make_pair(new_mask, i))); } } } printf("%d\n", sol); } return 0; }
Thursday, April 23, 2015
UVa 11813 - Shopping
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment