Pagini recente » Cod sursa (job #478332) | Cod sursa (job #601461) | Cod sursa (job #1599586) | Cod sursa (job #1362998) | Cod sursa (job #2640802)
#include <fstream>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
const int INF = 1000000000;
int n, m, k, x, y, z, i, j, top_heap = 0, mask, mini, v[18], dis[18][2020], heap[10020], d[17][(1 << 17) + 10];
bool ok[2020];
vector<pair<int, int > > t[2020];
vector<pair<int, int > >::iterator it;
pair<int, int > p;
int MINIM(int a, int b)
{
if (a <= b)
return a;
return b;
}
void UpHeap(int nod)
{
int tata = nod / 2;
if (tata && heap[tata] > heap[nod])
{
swap(heap[tata], heap[nod]);
UpHeap(tata);
}
}
void DownHeap(int nod)
{
int fiu = 2 * nod;
if (fiu <= top_heap && fiu + 1 <= top_heap && heap[fiu + 1] < heap[fiu])
++fiu;
if (fiu <= top_heap && heap[nod] > heap[fiu])
{
swap(heap[nod], heap[fiu]);
DownHeap(fiu);
}
}
void Insert(int nod)
{
heap[++top_heap] = nod;
UpHeap(top_heap);
}
void Sterge(int nod)
{
swap(heap[nod], heap[top_heap]);
--top_heap;
DownHeap(nod);
}
void Dijkstra(int nodst)
{
dis[nodst][nodst] = 0;
Insert(nodst);
ok[nodst] = true;
while (top_heap)
{
int nodc = heap[1];
ok[nodc] = false;
Sterge(1);
for (it = t[nodc].begin(); it < t[nodc].end(); ++it)
{
p = *it;
int vecin = p.second;
int cost = p.first;
if (dis[nodst][nodc] + cost < dis[nodst][vecin])
{
dis[nodst][vecin] = dis[nodst][nodc] + cost;
if (!ok[vecin])
{
ok[vecin] = true;
Insert(vecin);
}
}
}
}
}
int main()
{
f >> n >> m >> k;
for (i = 1; i <= k; ++i)
f >> v[i];
for (i = 1; i <= m; ++i)
{
f >> x >> y >> z;
t[x].push_back({z, y});
t[y].push_back({z, x});
}
v[0] = 1; v[++k] = n;
for (i = 0; i <= k; ++i)
for (j = 1; j <= n; ++j)
dis[v[i]][j] = INF;
for (i = 0; i <= k; ++i)
Dijkstra(v[i]);
for (i = 0; i <= k; ++i)
for (j = 1; j <= (1 << k); ++j)
d[i][j] = INF;
d[0][1] = 0;
for (mask = 1; mask < (1 << k); ++mask)
for (i = 0; i < k; ++i)
if (mask&(1 << i))
for (j = 0; j < k; ++j)
if (i != j && (mask&(1 << j)))
d[i][mask] = MINIM(d[i][mask], d[j][mask - (1 << i)] + dis[v[j]][v[i]]);
mini = INF;
for (i = 0; i <= k; ++i)
mini = MINIM(mini, d[i][((1 << k) - 1)] + dis[v[i]][n]);
g << mini;
return 0;
}