Pagini recente » Cod sursa (job #1276354) | Cod sursa (job #1456764) | Rating Aga Marian (AgaMarian) | Cod sursa (job #1857030) | Cod sursa (job #2610264)
#include <bits/stdc++.h>
#define oo (1 << 30)
#define DimMax 20006
using namespace std;
typedef int Atom;
struct Pereche{
Atom cost, nod;
};
ifstream fin ("ubuntzei.in");
ofstream fout ("ubuntzei.out");
int a[DimMax], drum[DimMax], dist[17][17];
vector <pair <int, int> > L[DimMax];
Pereche Q[DimMax];
Atom P;
int n, m, K;
int dp[17][1 << 17];
void Insert (Pereche Q[], int &P, Pereche x)
{
Q[++P] = x;
int fiu = P, parinte = P / 2;
while (parinte >= 1 && Q[parinte].cost > Q[fiu].cost)
{
std :: swap (Q[parinte], Q[fiu]);
fiu = parinte;
parinte /= 2;
}
}
Atom Remove (Pereche Q[], int &P)
{
int parinte = 1, fiu = 2;
Atom ret_val;
if (P == 0)
return -1;
ret_val = Q[1].nod;
std :: swap (Q[1], Q[P]);
P--;
while (fiu <= P)
{
if (fiu + 1 <= P && Q[fiu].cost > Q[fiu + 1].cost)
fiu++;
if (Q[fiu].cost < Q[parinte].cost)
{
std :: swap (Q[parinte], Q[fiu]);
parinte = fiu;
fiu *= 2;
}
else
fiu = P + 1;
}
return ret_val;
}
void Citire ()
{
int x, y, c;
fin >> n >> m >> K;
for (int i = 1; i <= K; i++)
fin >> a[i];
a[0] = 1;
K++;
a[K] = n;
for (int i = 1; i <= m; i++)
{
fin >> x >> y >> c;
L[x].push_back ({y, c});
L[y].push_back ({x, c});
}
}
void Dijkstra (int M)
{
int i, cost, nod;
Insert(Q, P, {0, M});
for (int i = 1; i <= n; i++)
drum[i] = oo;
drum[M] = 0;
while (P)
{
i = Remove(Q, P);
for (int j = 0; j < L[i].size(); j++)
{
nod = L[i][j].first;
cost = L[i][j].second;
if (drum[nod] > drum[i] + cost)
{
drum[nod] = drum[i] + cost;
Insert (Q, P, {drum[nod], nod});
}
}
}
}
void Construieste ()
{
for (int i = 0; i <= K; i++)
{
Dijkstra(a[i]);
for (int j = 0; j <= K; j++)
dist[i][j] = drum[a[j]];
}
}
void Initialiazare ()
{
for (int i = 0; i <= K; i++)
for (int j = 1; j <= (1 << K) - 1; j++)
dp[i][j] = oo;
for(int i = 0; i <= K; i++)
for(int j = 0; j <= K; j++)
dist[i][j] = oo;
}
void Dinamica ()
{
dp[0][1] = 0;
int ans = oo;
for (int i = 1; i <= (1 << K) - 1; i++)
for (int j = 0; j <= K; j++)
if ((i & (1 << j)) != 0)
for (int p = 0; p <= K; p++)
if ((i & (1 << p)) == 0)
dp[p][i | (1 << p)] = min (dp[p][i | (1 << p)],
dp[j][i] + dist[j][p]);
for (int i = 0; i <= K; i++)
ans = min (ans, dp[i][(1 << K) - 1] + dist[i][K]);
fout << ans << "\n";
}
int main()
{
Citire();
Initialiazare();
Construieste();
Dinamica();
return 0;
}