Pagini recente » Cod sursa (job #621796) | Cod sursa (job #2342946) | Cod sursa (job #589863) | Cod sursa (job #862684) | Cod sursa (job #2850933)
#include <bits/stdc++.h>
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
const int K = 17, N = 2001, C = (1 << 16), INF32 = 0x3f3f3f3f;
int n, m, k, x, y, w, pr[K], dist[K][N], ans, dp[C][K]; // dp[i][j] = costul minim pt. a ajunge la starea i, stiind ca ultimul prieten vizitat este j
struct muchie{
int y, w;
bool operator < (muchie muc) const{
return make_pair(w, y) < make_pair(muc.w, muc.y);
}
muchie(int spre, int cost){
y = spre;
w = cost;
}
};
vector<muchie> c[N];
bool vis[N];
void djikstra(int start, int ind){
set<muchie> s;
for(int i = 1; i <= n; i++){
dist[ind][i] = INF32;
vis[i] = 0;
}
dist[ind][start] = 0;
s.insert({start, 0});
for(int i = 0; i < n; i++){
int v = s.begin()->y; // pt. ca begin() returneaza pointer la priumul element
s.erase(s.begin());
vis[v] = 1;
for(auto e: c[v]){
if(!vis[e.y] && dist[ind][e.y] > dist[ind][v] + e.w){
s.erase({e.y, dist[ind][e.y]});
dist[ind][e.y] = dist[ind][v] + e.w;
s.insert({e.y, dist[ind][e.y]});
}
}
}
}
int main(){
f >> n >> m >> k;
for(int i = 1; i <= k; i++)
f >> pr[i];
for(int i = 0; i < m; i++){
f >> x >> y >> w;
muchie MX(y, w), MY(x, w);
c[x].push_back(MX);
c[y].push_back(MY);
}
f.close();
for(int i = 1; i < (1 << (k + 1)); i++){
for(int j = 0; j <= k + 1; j++)
dp[i][j] = INF32;
}
// 0 - Cluj ; k + 1 - Vama Veche
djikstra(1, 0); // calculare dist de la Cluj la restul prietenilor
pr[k + 1] = n;
for(int i = 1; i <= n; i++)
dist[k + 1][i] = INF32;
dist[k + 1][n] = 0;
for(int i = 1; i <= k; i++){ // dist. de la fiecare prieten la toate celelalte localitati
djikstra(pr[i], i);
dp[(1 << (i - 1))][i] = dist[0][pr[i]]; // punem valoarea distantei de la Cluj la prieteni starii in care este vizitat doar prietenul respectiv
}
dp[1 << k][k + 1] = dist[0][n]; // pt. caz special in care k = 0
for(int i = 1; i < (1 << (k + 1)); i++){
for(int j = 1; j <= k; j++){
if((1 << (j - 1)) & i){ // am fost deja pe la prietenul j
for(int l = 1; l <= k + 1; l++){
if(((1 << (l - 1)) & i) == 0) // nu am fost inca pe la prietenul l
dp[i | (1 << (l - 1))][l] = min(dp[i | (1 << (l - 1))][l], dp[i][j] + dist[j][pr[l]]);
}
}
}
}
g << dp[(1 << (k + 1)) - 1][k + 1];
g.close();
}