Pagini recente » Cod sursa (job #1780036) | Cod sursa (job #1666693) | Cod sursa (job #1470228) | Cod sursa (job #3254085) | Cod sursa (job #1110167)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin ("ubuntzei.in");
ofstream fout ("ubuntzei.out");
struct Edge {
long x, c;
};
const long K = 20, N = 2001, S = (1 << 16), inf = 2000000000;
long n, m, k;
long must [K], h [N], l[N] [N], poz [N], z, dp [S][K], final;
vector <Edge> v [N];
void read () {
long i, x, y, c;
Edge temp;
fin >> n >> m >> k;
for (i = 1; i <= k; i ++)
fin >> must [i];
must [0] = 1;
for (i = 1; i <= m; i ++) {
fin >> x >> y >> c;
temp.x = y;
temp.c = c;
v [x].push_back (temp);
temp.x = x;
v [y].push_back (temp);
}
}
void init () {
long i;
h [0] = 0;
for (i = 1; i <= n; i ++) {
l [z][i] = inf;
poz [i] = -1;
}
}
void up (long x) {
long father, aux;
while (x > 1) {
father = x >> 1;
if (l [z][h [father]] > l [z][h [x]]) {
poz [h [father]] = x;
poz [h [x]] = father;
aux = h [father];
h [father] = h [x];
h [x]= aux;
x= father;
}
else break;
}
}
void down (long x) {
long left, right, son, aux;
while (1) {
left = x << 1;
if (left <= h [0]) {
son = left;
right = left + 1;
if (right <= h [0] && l [z][h[right]]< l [z][h [left]])
son = right;
if (l [z][h [son]] < l [z][h [x]]) {
poz [h [son]] = x;
poz [h [x]] = son;
aux = h [son];
h [son] = h [x];
h [x] = aux;
x = son;
}
else break;
}
else break;
}
}
void insert (long x) {
h [++ h [0]] = x;
poz [x] = h [0];
up (poz [x]);
}
void pop () {
h [1] = h [h [0]];
poz [h [1]] = 1;
h [0] --;
down (1);
}
void dijkstra () {
long a, d;
Edge temp;
vector <Edge> :: iterator it;
init ();
h [++ h [0]] = z;
l [z][z]= 0;
while (h [0]) {
a = h [1];
pop ();
for (it = v [a].begin (); it != v [a].end (); it ++) {
temp = *it;
d = temp.c + l [z][a];
if (d < l [z][temp.x]) {
l [z][temp.x] = d;
if (poz [temp.x] != -1)
up (poz [temp.x]);
else
insert (temp.x);
}
}
}
}
long ciclu (long config, long x) {
long i, e;
if (dp [config][x] == -1) {
dp [config][x] = inf;
for (i = 0; i <= k; i ++)
if (must [i] != must [x]){
if (config & (1 << i))
if (!(i == 0 && config != (1 << x) + 1)) {
e = ciclu (config ^ (1 << x), i) + l [must [i]][must [x]];
if (e < dp [config][x])
dp [config][x] = e;
}
}
}
return dp [config][x];
}
void solve () {
long i, min1, g, j;
z = 1;
for (i = 0; i <= k; i ++) {
z = must [i];
dijkstra ();
}
final = (1 << (k + 1)) - 1;
min1 = inf;
for (i = 0; i <= final; i ++)
for (j = 0; j <= k; j ++)
dp [i][j] = -1;
dp [1][0] = 0;
for (i = 0; i <= k; i ++) {
g = ciclu (final, i) + l [must [i]][n];
if (min1 > g)
min1 = g;
}
fout << min1 << "\n";
}
int main () {
read ();
solve ();
return 0;
}