Pagini recente » Cod sursa (job #3199545) | Cod sursa (job #1186158) | Cod sursa (job #3249997) | Cod sursa (job #1405743) | Cod sursa (job #698571)
Cod sursa(job #698571)
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <set>
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int K = 18;
const int N = 2002;
int n, k;
int obj[K];
int d[K][K];
vector <int> g[N];
vector <int> c[N];
void Read()
{
int m;
in >> n >> m >> k;
for (int i = 1; i <= k; ++i)
in >> obj[i];
obj[0] = 1;
obj[k+1] = n;
while (m--)
{
int a, b, cost;
in >> a >> b >> cost;
g[a].push_back(b), c[a].push_back(cost);
g[b].push_back(a), c[b].push_back(cost);
}
}
set < pair<int,int> > s; // cost, nod
int cost[N];
void Check(int cst, int node)
{
for (int i = 0; i < g[node].size(); ++i) {
int next = g[node][i];
if (cst + c[node][i] < cost[next]) {
cost[next] = cst + c[node][i];
s.insert(make_pair(cost[next], next));
}
}
}
void Dijkstra(int node)
{
memset(cost, 0x3f3f3f3f, sizeof(cost));
cost[node] = 0;
s.insert(make_pair(0, node));
for (int i = 1; i <= n; ++i) {
pair <int,int> curState = *s.begin();
int cst = curState.first;
int node = curState.second;
s.erase(s.begin());
Check(cst, node);
}
}
void UpdateDistances(int node)
{
for (int i = 1; i <= k+1; ++i)
d[node][i] = cost[obj[i]];
}
int a[K][1 << K];
inline int bitter(int x)
{
return 1 << (x-1);
}
int HamiltonCheck()
{
memset(a, 0x3f3f3f3f, sizeof(a));
for (int i = 1; i <= k; ++i)
a[i][1 << (i-1)] = d[0][i];
for (int conf = 0; conf < (1<<k) - 1; ++conf)
for (int i = 1; i <= k; ++i)
if (a[i][conf] < 0x3f3f3f3f)
for (int j = 1; j <= k; ++j)
if (bitter(j)^conf && a[j][conf + bitter(j)] > a[i][conf] + d[i][j])
a[j][conf + bitter(j)] = a[i][conf] + d[i][j];
int best = 0x3f3f3f3f;
for (int i = 1; i <= k; ++i)
if (a[i][(1<<k) - 1] + d[i][k+1] < best)
best = a[i][(1<<k) - 1] + d[i][k+1];
return best;
}
int main()
{
Read();
for (int i = 0; i <= k; ++i) {
Dijkstra(obj[i]); // Merge
UpdateDistances(i);
}
if (k == 0)
{
out << d[0][k+1] << "\n";
return 0;
}
out << HamiltonCheck() << "\n";
return 0;
}