Pagini recente » Monitorul de evaluare | Cod sursa (job #2451725) | Cod sursa (job #2190628) | Cod sursa (job #558220) | Cod sursa (job #2565020)
#include<fstream>
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<climits>
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int NMax = 2000, KMax = 17, oo = 1e9;
const long long OO = 1e15;
vector <int> G[NMax+5];
priority_queue <pair<int,int>> Q;
int N, M, K, Ck[KMax+5], D[NMax+5], Use[NMax+5], C[NMax+5][NMax+5];
long long DP[1<<(KMax+2)][KMax+5];
void Read() {
in >> N >> M >> K;
for (int i = 1; i <= K; i++)
in >> Ck[i];
Ck[K+1] = 1;
Ck[K+2] = N;
for (int i = 0,x,y,c; i < M; i++) {
in >> x >> y >> c;
C[x][y] = C[y][x] = c;
G[x].push_back(y);
G[y].push_back(x);
}
}
int find_min() {
while(Use[Q.top().second])
Q.pop();
int res = Q.top().second;
Q.pop();
return res;
}
void Dijkstra (int Node) {
for (int i = 1; i <= N; i++)
D[i] = oo;
memset(Use,0,sizeof Use);
D[Node] = 0;
Q.push(make_pair(D[Node], Node));
for(int i = 1; i <= N && !Q.empty(); i++) {
int Nod = find_min();
Use[Nod] = 1;
for (auto Vecin : G[Nod]) {
int Cost = C[Nod][Vecin];
if(D[Vecin] > D[Nod]+Cost) {
D[Vecin] = D[Nod] + Cost;
Q.push(make_pair(-D[Vecin], Vecin));
}
}
}
for (int i = 1; i <= K+2; i++)
if (Ck[i] != Node)
C[Node][Ck[i]] = D[Ck[i]];
}
void Solve() {
for (int i = 1; i <= K+2; i++)
Dijkstra(Ck[i]);
for(int i = 0; i < (1 << (K+2)); i++)
for (int j = 0; j < K+2; j++)
DP[i][j] = OO;
DP[1][0] = 0;
for (int Conf = 1; Conf < (1<<(K+2)); Conf++)
for (int i = 0; i < K+2; i++) {
if (Conf & (1<<i))
for (int j = 0; j < K + 2; j++) {
if (Conf & (1<<j))
DP[Conf][i] = min(DP[Conf][i], DP[Conf^(1<<i)][j] + C[Ck[i+1]][Ck[j+1]]);
}
}
int Sol = DP[(1<<(K+2))-1][K + 1];
out << Sol << '\n';
}
int main() {
Read();
Solve();
}