Pagini recente » Cod sursa (job #2190676) | Cod sursa (job #1811421) | Cod sursa (job #503830) | Cod sursa (job #451963) | Cod sursa (job #2463327)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int n, m, k, orase[20], heap[2019], drum[2019][2019], p[2019], dp[(1 << 15)][20];
bool viz[2019];
vector <pair <int, int> > Muchii[2019];
void UpHeap(int poz, int *v)
{
if (poz / 2 < 1)
return;
int nodfiu = heap[poz];
int nodtata = heap[poz / 2];
if (v[nodfiu] < v[nodtata])
{
swap(p[nodfiu], p[nodtata]);
swap(heap[poz], heap[poz / 2]);
UpHeap(poz / 2, v);
}
}
void DownHeap(int poz, int *v)
{
if (poz * 2 > heap[0])
return;
int nodtata = heap[poz];
int nodfiu1 = heap[poz * 2];
int nodfiu2 = heap[poz * 2 + 1];
if (v[nodtata] > v[nodfiu1] || v[nodtata] > v[nodfiu2])
{
if (v[nodfiu1] <= v[nodfiu2])
{
swap(p[nodfiu1], p[nodtata]);
swap(heap[poz], heap[poz * 2]);
DownHeap(poz * 2, v);
}
else
{
swap(p[nodfiu2], p[nodtata]);
swap(heap[poz], heap[poz * 2 + 1]);
DownHeap(poz * 2 + 1, v);
}
}
}
void Adauga(int nod, int *v)
{
viz[nod] = true;
heap[++heap[0]] = nod;
p[nod] = heap[0];
UpHeap(nod, v);
}
void Sterge(int poz, int *v)
{
viz[heap[poz]] = false;
swap(heap[poz], heap[heap[0]]);
heap[heap[0]] = n + 1;
--heap[0];
DownHeap(poz, v);
}
void Dijkstra(int x)
{
heap[0] = 0;
for (int i = 1; i <= n + 1; ++i)
{
heap[i] = n + 1;
drum[x][i] = (1 << 30);
viz[i] = false;
}
drum[x][x] = 0;
Adauga(x, drum[x]);
while (heap[0] > 0)
{
int nod = heap[1];
Sterge(1, drum[x]);
for (int j = 0; j < Muchii[nod].size(); ++j)
{
int vecin = Muchii[nod][j].first;
int cost = Muchii[nod][j].second;
if (drum[x][vecin] > drum[x][nod] + cost)
{
drum[x][vecin] = drum[x][nod] + cost;
if (viz[vecin] == true)
{
UpHeap(p[vecin], drum[x]);
}
else
{
Adauga(vecin, drum[x]);
}
}
}
}
}
int main()
{
fin >> n >> m >> k;
for (int i = 1; i <= k; ++i)
fin >> orase[i];
for (int i = 1; i <= m; ++i)
{
int x, y, z;
fin >> x >> y >> z;
Muchii[x].push_back({y, z});
Muchii[y].push_back({x, z});
}
Dijkstra(1);
for (int i = 1; i <= k; ++i)
Dijkstra(orase[i]);
int stare = (1 << k);
for (int i = 0; i < stare; ++i)
{
for (int j = 0; j < k; ++j)
{
dp[stare][j] = (1 << 30);
}
}
for (int i = 0; i < k; ++i)
dp[(1 << i)][i] = drum[1][orase[i + 1]];
for (int i = 1; i < stare; ++i)
{
for (int j = 0; j < k; ++j)
{
if ((stare >> j) & 1 == 1)
{
for (int t = 0; t < k; ++t)
{
if ((stare >> t) & 1 == 0)
{
dp[((1 << t) | stare)][t] = min(dp[((1 << t) | stare)][t], dp[stare][j] + drum[orase[j + 1]][orase[t + 1]]);
}
}
}
}
}
int minim = (1 << 30);
for (int i = 0; i < k; ++i)
minim = min(minim, dp[(1 << k) - 1][i] + drum[orase[i + 1]][n]);
fout << minim;
fin.close();
fout.close();
return 0;
}