Pagini recente » Cod sursa (job #36738) | Cod sursa (job #2026565) | Cod sursa (job #35812) | Cod sursa (job #36719) | Cod sursa (job #1154107)
#include <cstdio>
#include <cstring>
#include <cassert>
#include <vector>
#include <algorithm>
using namespace std;
const int oo = 0x3f3f3f3f;
const int NIL = -1;
const int MAX_V = 500;
const int MAX_N = 50;
class Reader {
public:
Reader(FILE *_stream, const int _size = (1 << 16)):
size(_size),
pointer(0),
buffer(new char[_size]),
stream(_stream) {
assert(fread(buffer, 1, size, stream) != 0);
}
template<class IntType>
IntType NextInt() {
IntType value = 0;
bool negative = false;
while ((Current() < '0' || Current() > '9') && Current() != '-')
NextPosition();
if (Current() == '-') {
negative = true;
NextPosition();
}
while(Current() >= '0' && Current() <= '9') {
value = value * 10 + Current() - '0';
NextPosition();
}
if (negative)
value = -value;
return value;
}
Reader &operator>>(int &value) {
value = NextInt<int>();
return *this;
}
private:
int size, pointer;
char *buffer;
FILE *stream;
char Current() const {
return buffer[pointer];
}
void NextPosition() {
if(++pointer == size) {
assert(fread(buffer, 1, size, stream) != 0);
pointer = 0;
}
}
};
int N, V, G[MAX_V][MAX_V], Source, Answer;
int Destinations[MAX_N], Cost[MAX_N + 1][MAX_N + 1];
void Dijkstra(const int source, int distances[MAX_V]) {
bool used[MAX_V];
memset(used, 0, sizeof(used));
for (int x = 0; x < V; ++x)
distances[x] = oo;
distances[source] = 0;
int x = source;
do {
for (int y = 0; y < V; ++y)
if (!used[y])
distances[y] = min(distances[y], distances[x] + G[x][y]);
used[x] = true;
x = NIL;
for (int y = 0; y < V; ++y)
if (!used[y] && (x == NIL || distances[y] < distances[x]))
x = y;
} while (x != NIL);
}
void BuildCost() {
vector<int> vertices;
vertices.push_back(Source);
for (int x = 0; x < N; ++x)
vertices.push_back(Destinations[x]);
sort(vertices.begin(), vertices.end());
vertices.erase(unique(vertices.begin(), vertices.end()), vertices.end());
int newV = int(vertices.size()), newIndex[MAX_V];
memset(newIndex, -1, sizeof(newIndex));
for (int i = 0; i < newV; ++i)
newIndex[vertices[i]] = i;
for (int x = 0; x < N; ++x)
Destinations[x] = newIndex[Destinations[x]];
for (int i = 0; i < newV; ++i) {
int distances[MAX_V];
Dijkstra(vertices[i], distances);
for (int j = 0; j < newV; ++j)
Cost[i][j] = distances[vertices[j]];
}
V = newV;
}
void Solve() {
BuildCost();
int dp[MAX_N + 1][MAX_N][MAX_N];
memset(dp, oo, sizeof(dp));
for (int length = 1; length <= N; ++length) {
for (int x = 0; x < V; ++x) {
for (int first = 0, last = length - 1; last < N; ++first, ++last) {
for (int split = first; split <= last; ++split) {
int current = Cost[x][Destinations[split]];
if (split > first)
current += dp[Destinations[split]][first][split - 1];
if (split < last)
current += dp[Destinations[split]][split + 1][last];
dp[x][first][last] = min(dp[x][first][last], current);
}
}
}
}
Answer = dp[Source][0][N - 1];
}
void Read() {
assert(freopen("team.in", "r", stdin));
Reader in = Reader(stdin);
int E;
in >> N >> V >> E;
memset(G, oo, sizeof(G));
for (int x = 0; x < V; ++x)
G[x][x] = 0;
for (; E > 0; --E) {
int x, y, c;
in >> x >> y >> c;
--x;
--y;
G[x][y] = G[y][x] = c;
}
for (int x = 0; x < N; ++x) {
in >> Destinations[x];
--Destinations[x];
}
Source = 0;
fclose(stdin);
}
void Print() {
assert(freopen("team.out", "w", stdout));
printf("%d\n", Answer);
fclose(stdout);
}
int main() {
Read();
Solve();
Print();
return 0;
}