Pagini recente » Cod sursa (job #2627181) | Cod sursa (job #313527) | Cod sursa (job #2475229) | Cod sursa (job #693256) | Cod sursa (job #2386291)
#include <fstream>
#include <cstring>
#include <vector>
#include <utility>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
const int ConfMax = (1 << 15), KMax = 15, NMax = 2000, oo = 2e9;
int N, M, K, DP[ConfMax + 5][KMax + 5], C[KMax + 5][KMax + 5], P[NMax + 5], D[NMax + 5], S;
///Cij - distanta minima de la nodul V[i] la nodul V[j]
vector < pair<int, int> > G[NMax + 5];
vector <int> V;
struct heap{int cod, val;} H[4 * NMax + 5];
void Up(int i)
{
while(i > 1 && H[i].val < H[i / 2].val)
{
swap(P[H[i].cod], P[H[i / 2].cod]);
swap(H[i], H[i / 2]);
}
}
void Down(int i)
{
int son = 1;
while(son)
{
son = 0;
if(2 * i <= S && H[i].val > H[2 * i].val)
son = 2 * i;
if(2 * i + 1 <= S && H[son].val > H[2 * i + 1].val)
son = 2 * i + 1;
if(son)
{
swap(P[H[i].cod], P[H[son].cod]);
swap(H[i], H[son]);
i = son;
}
}
}
void Delete(int i)
{
swap(P[H[i].cod], P[H[S].cod]);
swap(H[i], H[S]);
S--; Up(i); Down(i);
}
void Update(int i, int V)
{
H[i].val = V; Down(i);
}
void Dijkstra(int k)
{
int Nod = V[k];
for(int i = 1; i <= N; i++)
D[i] = oo, P[i] = i, H[i].cod = i, H[i].val = oo;
S = N; D[Nod] = 0; Update(P[Nod], 0);
while(S)
{
int Nod = H[1].cod, Vecin, Cost; Delete(1);
for(auto x : G[Nod])
{
Vecin = x.first, Cost = x.second;
if(D[Nod] + Cost < D[Vecin])
{
D[Vecin] = D[Nod] + Cost;
Update(P[Vecin], D[Vecin]);
}
}
}
for(int i = 0; i < K; i++)
C[k][i] = D[V[i]];
}
void Read()
{
fin >> N >> M >> K;
V.push_back(1), V.push_back(N);
for(int i = 1, x; i <= K; i++)
fin >> x, V.push_back(x);
K += 2;
for(int i = 0, x, y, c; i < M; i++)
{
fin >> x >> y >> c;
G[x].push_back({y, c});
G[y].push_back({x, c});
}
}
void Solve_and_Print()
{
int Lim = (1 << K) - 1;
for(int i = 1; i <= Lim; i++)
for(int j = 0; j <= K; j++)
DP[i][j] = oo;
DP[1][0] = 0;
for(int i = 1; i <= Lim; i++)
for(int j = 0; j < K; j++)
if(i & (1 << j))
{
for(int k = 0; k < K; k++)
{
DP[i][j] = min(DP[i][j], DP[i - (1 << j)][k] + C[k][j]);
}
}
fout << DP[Lim][1] << '\n';
}
int main()
{
Read();
for(int i = 0; i < K; i++) Dijkstra(i);
Solve_and_Print();
return 0;
}