Pagini recente » Cod sursa (job #1121224) | Cod sursa (job #2391760) | Cod sursa (job #3125259) | Cod sursa (job #1929769) | Cod sursa (job #1871589)
/**
* Worg
*/
#include <set>
#include <cstdio>
#include <vector>
#include <algorithm>
using std::vector;
using std::set;
FILE *fin = freopen("team.in", "r", stdin);
FILE *fout = freopen("team.out", "w", stdout);
const int MAX_P = 1 + 50;
const int MAX_N = 1 + 500;
const int MAX_INF = 0x3fffffff;
/*------- Structures --------*/
struct Edge {
int vertex, cost;
Edge() {}
Edge(const int _vertex, const int _cost) {vertex = _vertex; cost = _cost;}
bool operator <(const Edge &other) const {
return this->cost < other.cost;
}
};
/*------- Input data --------*/
int P, N, M;
vector< Edge > graph[MAX_N];
int finish[MAX_P];
/*------- Algorithm data --------*/
int min_dist[MAX_N][MAX_N];
set< Edge > heap;
int dp[MAX_P][MAX_P][MAX_N];
/*------- --------*/
void ReadInput() {
scanf("%d%d%d", &P, &N, &M);
for(int i = 1; i <= M; i++) {
int u, v, c; scanf("%d%d%d", &u, &v, &c);
graph[u].push_back(Edge(v, c));
graph[v].push_back(Edge(u, c));
}
for(int i = 1; i <= P; i++) {
scanf("%d", &finish[i]);
}
}
void Initialize() {
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= N; j++) {
min_dist[i][j] = MAX_INF;
}
}
for(int i = 1; i <= P; i++) {
for(int j = 1; j <= P; j++) {
for(int k = 1; k <= N; k++) {
dp[i][j][k] = MAX_INF;
}
}
}
for(int i = 1; i <= P; i++) {
dp[i][i][finish[i]] = 0;
}
}
void RunDijkstra(int source) {
heap.insert(Edge(source, 0));
while(!heap.empty()) {
Edge top_edge = *heap.begin(); heap.erase(heap.begin());
int node = top_edge.vertex, cost = top_edge.cost;
if(min_dist[source][node] == MAX_INF) {
min_dist[source][node] = cost;
for(Edge edge : graph[node]) {
if(min_dist[source][edge.vertex] == MAX_INF) {
heap.insert(Edge(edge.vertex, cost + edge.cost));
}
}
}
}
}
void GetDistances() {
RunDijkstra(1); // Rulam Dijsktra cu pornire din locul unde se afla discoteca
for(int i = 1; i <= P; i++) {
RunDijkstra(finish[i]);
}
}
int GetSolution(int left, int right, int node) { // Costul minim pentru a duce persoanele din [{st}, {dr}] acasa, pornind din {node}
if(left > right) {
return 0;
} else if(dp[left][right][node] != MAX_INF) {
return dp[left][right][node];
} else {
for(int x = left; x <= right; x++) {
dp[left][right][node] = std::min(dp[left][right][node],
GetSolution(left, x - 1, finish[x]) + GetSolution(x + 1, right, finish[x]) + min_dist[node][finish[x]]);
}
return dp[left][right][node];
}
}
int main() {
ReadInput();
Initialize();
GetDistances();
printf("%d\n", GetSolution(1, P, 1));
return 0;
}