Pagini recente » Cod sursa (job #474026) | Cod sursa (job #1767646) | Cod sursa (job #2987121) | Cod sursa (job #3223339) | Cod sursa (job #2936708)
#include <fstream>
#include <iostream>
#include <climits>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
//dp[mask][i] = lungimea minima a unui traseu care trece prin
//localitatile date de mask si care se termina in localitatea
//i
//dp[2^i][i] = distmin(0, i)
//dp[masca][j] = min(dp[masca - 2^j][oricare din bitii din masca - 2^j]
// + distmin(localitatea data de bit, j))
//ans = min(dp[2^k - 1][i] + distmin(i, n - 1)), cu 0 <= i <= n - 1
//lmao, m-am tampit, am crezut ca in enunt scrie max(15, n - 2), nu min
const int NMAX = 2003;
const int KMAX = 16;
vector <pair <int, int> > g[NMAX];
struct ob
{
int last;
int dist;
};
bool operator <(ob a, ob b)
{
return a.dist > b.dist;
}
int d[NMAX][NMAX];
int c[KMAX];
priority_queue <ob> q;
int dp[(1 << KMAX)][NMAX];
bool special[NMAX];
void dijkstra(int nod)
{
q.push({nod, 0});
d[nod][nod] = 0;
while (!q.empty())
{
ob f = q.top();
q.pop();
if (d[nod][f.last] < f.dist)
{
continue;
}
d[nod][f.last] = f.dist;
for (pair <int, int> u : g[f.last])
if (d[nod][u.first] > d[nod][f.last] + u.second)
{
d[nod][u.first] = d[nod][f.last] + u.second;
q.push({u.first, d[nod][u.first]});
}
}
}
pair <int, int> masca[KMAX];
int main()
{
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int n, m, i, j;
fin >> n >> m;
int k;
fin >> k;
for (i = 0; i < k; i++)
{
fin >> c[i];
c[i]--;
special[c[i]] = 1;
}
for (i = 1; i <= m; i++)
{
int a, b, x;
fin >> a >> b >> x;
a--;
b--;
g[a].push_back({b, x});
g[b].push_back({a, x});
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
d[i][j] = INT_MAX / 2;
dijkstra(i);
}/*
for (i = 0; i < n; i++, fout << "\n")
for (j = 0; j < n; j++)
fout << d[i][j] << " ";
fout << "\n";*/
int lim = (1 << k);
for (i = 0; i < lim; i++)
for (j = 0; j < n; j++)
dp[i][j] = INT_MAX / 2;
for (i = 0; i < k; i++)
dp[1 << i][c[i]] = d[0][c[i]];
for (i = 0; i < n; i++)
//if (!special[i])
{
// cout << i << " ";
dp[0][i] = d[0][i];
}
for (i = 1; i < lim; i++)
{
vector <int> aux;
masca[i].second = i;
for (j = 0; (1 << j) <= i; j++)
if ((1 << j) & i)
{
masca[i].first++;
}
}
sort(masca + 1, masca + lim);
for (i = 1; i < lim; i++)
{
//fout << masca[i].first << " " << masca[i].second << "\n";
vector <int> aux;
for (j = 0; (1 << j) <= masca[i].second; j++)
if ((1 << j) & masca[i].second)
{
aux.push_back(j);
}
for (j = 0; j < aux.size(); j++)
{
//dp[i][j] = min(dp[i - (1 << j)][
for (int ind = 0; ind < n; ind++)
if (ind != c[aux[j]])
{
// fout << dp[masca[i].second - (1 << aux[j])][ind] << " " << d[ind][c[aux[j]]] << "\n";
// fout << masca[i].second << " " << aux[j] << " " << masca[i].second - (1 << aux[j]) << " " << ind << " " << dp[masca[i].second - (1 << aux[j])][ind] << "\n";
dp[masca[i].second][c[aux[j]]] = min(dp[masca[i].second][c[aux[j]]],
dp[masca[i].second - (1 << aux[j])][ind] + d[ind][c[aux[j]]]);
}
}
}
int ans = INT_MAX / 2;
for (i = 0; i < n; i++)
{
//fout << dp[lim - 1][i] << " " << d[i][n - 1] << "\n";
ans = min(ans, dp[lim - 1][i] + d[i][n - 1]);
}
fout << ans;
}