Pagini recente » Cod sursa (job #1858454) | Cod sursa (job #1909559) | Cod sursa (job #1558078) | Cod sursa (job #1998969) | Cod sursa (job #1946753)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define nMax 2005
#define mMax 10005
#define inf (1 << 30)
using namespace std;
// c[i][j] - dist minima dintre nodul i si j din k
// dp[i][j] - distanta minima a unui laant ce se termina cu j si trece
// prin nodurile date de pozitiile cifrelor de 1 in configuratia binara a lui i
int n, m, K, dist[nMax], c[19][19], dp[1 << 17][19], k[19];
typedef struct {
int nod, cost;
} muchie;
muchie h;
vector <muchie> v[nMax];
queue <int> C;
void read()
{
ifstream fin("ubuntzei.in");
fin >> n >> m >> K;
int x;
for(int i = 1; i <= K; ++i)
fin >> k[i];
K += 2;
k[K - 1] = n;
k[0] = 1;
for(int i = 1; i <= m; ++i){
fin >> x >> h.nod >> h.cost;
v[x].push_back(h);
swap(x, h.nod);
v[x].push_back(h);
}
}
void dijkstra(int nod, int index)
{
int x, y;
for(int i = 0; i < K; ++i)
c[index][i] = inf;
for(int i = 1; i <= n; ++i)
dist[i] = inf;
C.push(nod);
dist[nod] = 0;
while(!C.empty()){
x = C.front();
C.pop();
for(int i = 0; i < v[x].size(); ++i){
y = v[x][i].nod;
if(dist[x] + v[x][i].cost < dist[y]){
dist[y] = dist[x] + v[x][i].cost;
C.push(y);
}
}
}
for(int i = 0; i < K; ++i)
c[index][i] = min(c[index][i], dist[k[i]]);
}
void solve()
{
for(int i = 0; i < K; ++i)
dijkstra(k[i], i); // calculez distantele de la al i-lea nod din la toate celelalte noduri din k
// calculam un ciclu hamiltonian format doar din cele K + 1 noduri din k
for(int i = 0; i < (1 << K); ++i)
for(int j = 0; j < K; ++j)
dp[i][j] = inf;
dp[1][0] = 0;
for(int i = 1; i < (1 << K); ++i)
for(int j = 0; j < K; ++j)
if(i & (1 << j)) // daca j face parte din lantul i
for(int h = 0; h < K; ++h)
if(c[h][j] != inf && i & (1 << h)) // daca exista drum intre h si j si daca h face parte din lantul i
dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][h] + c[h][j]);
ofstream fout("ubuntzei.out");
fout << dp[(1 << K) - 1][K - 1];
}
int main()
{
read();
solve();
return 0;
}