Pagini recente » Borderou de evaluare (job #683744) | Borderou de evaluare (job #1119185) | Borderou de evaluare (job #609512) | Borderou de evaluare (job #2692012) | Cod sursa (job #3278999)
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#define nl '\n'
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
const int NMAX = 2e3+5, KMAX = 17, INF = 1e9+5;
int n, m, k, translate[NMAX], ubuntz[KMAX+5], cost[KMAX][KMAX], dist[NMAX], dp[KMAX][(1<<KMAX)];
struct muchie
{
int nod, cost;
};
vector<muchie> adj[NMAX];
muchie crt;
bool operator <(const muchie& a, const muchie& b)
{
if (a.cost == b.cost)
return a.nod < b.nod;
return a.cost < b.cost;
}
set<muchie> q;
int main()
{
fin >> n >> m;
fin >> k;
for (int i = 1; i <= k; i++)
{
fin >> ubuntz[i];
translate[ubuntz[i]] = i;
}
ubuntz[0] = 1;
translate[1] = 0;
ubuntz[k+1] = n;
translate[n] = k+1;
k+=2;
for (int i = 1; i <= m; i++)
{
int u, v, w;
fin >> u >> v >> w;
adj[u].push_back({v, w});
adj[v].push_back({u, w});
}
for (int start = 0; start < k; start++)
{
for (int i = 1; i <= n; i++)
dist[i] = INF;
dist[ubuntz[start]] = 0;
q.insert({ubuntz[start], 0});
while (!q.empty())
{
crt = *(q.begin());
q.erase(q.begin());
for (const muchie& mm : adj[crt.nod])
{
if (crt.cost+mm.cost < dist[mm.nod])
{
if (dist[mm.nod] != INF)
q.erase({mm.nod, dist[mm.nod]});
dist[mm.nod] = crt.cost+mm.cost;
q.insert({mm.nod, dist[mm.nod]});
}
}
}
for (int i = 0; i < k; i++)
cost[start][i] = dist[ubuntz[i]];
}
for (int i = 0; i < k; i++)
for (int mask = 0; mask < (1<<k); mask++)
dp[i][mask] = INF;
dp[0][1] = 0;
for (int mask = 2; mask < (1<<k); mask++)
{
if (!(mask&1))
continue;
for (int j = 0; j < k; j++)
{
if (mask&(1<<j))
{
for (int p = 0; p < k; p++)
{
if (p == j)
continue;
if (mask&(1<<p))
dp[j][mask] = min(dp[j][mask], dp[p][mask^(1<<j)]+cost[p][j]);
}
}
}
}
fout << dp[k-1][(1<<k)-1];
return 0;
}