Pagini recente » Cod sursa (job #733554) | Cod sursa (job #2189053) | Cod sursa (job #939486) | Cod sursa (job #2519433) | Cod sursa (job #2718312)
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
vector <pair <int, int>> v[2001];
struct el
{
int nod, c;
bool operator <(const el &alt) const
{
return c > alt.c;
}
};
priority_queue <el> p;
int d[2001];
bool b[2001];
void dijkstra(int n, int s)
{
int i, j, x, y;
el na;
while (p.empty() == 0)
p.pop();
for (i = 1; i<=n; i++)
{
d[i] = 1<<30;
b[i] = 0;
}
d[s] = 0;
p.push({s, 0});
for (i = 1; i<n; i++)
{
while (b[p.top().nod])
p.pop();
na = p.top();
b[na.nod] = 1;
p.pop();
for (j = 0; j<v[na.nod].size(); j++)
{
x = v[na.nod][j].first;
y = v[na.nod][j].second;
if (d[x] > na.c + y)
{
d[x] = na.c + y;
p.push({x, d[x]});
}
}
}
}
int cost[15][15];
vector <int> nr[16];
int dp[15][32768];
//dp[i][j] = costul minim pentru a trece prin nodurile indicate de parametrul i, daca ultimul nod prin care am trecut este j
//j este determinat in mod exclusiv de i in recurenta, adica bitul scos din i in recurenta este insusi j.
int main()
{
int n, m, k, c[15];
int i, j, x, y, z;
fin >> n >> m >> k;
for (i = 0; i<k; i++)
fin >> c[i];
for (i = 1; i<=m; i++)
{
fin >> x >> y >> z;
v[x].push_back({y, z});
v[y].push_back({x, z});
}
for (i = 0; i<k; i++)
{
dijkstra(n, c[i]);
for (j = 0; j<k; j++)
cost[i][j] = d[c[j]];
}
dijkstra(n, 1);
if (k == 0)
{
fout << d[n];
return 0;
}
for (i = 0; i < (1<<k); i++)
{
nr[__builtin_popcount(i)].push_back(i);
for (j = 0; j<k; j++)
dp[j][i] = 1<<30;
}
for (i = 0; i<k; i++)
dp[i][1<<i] = d[c[i]];
for (x = 2; x<=k; x++)
for (y = 0; y<nr[x].size(); y++)
{
z = nr[x][y];
for (i = 0; i<k; i++)
if (z & (1<<i))
{
for (j = 0; j<k; j++)
dp[i][z] = min(dp[i][z], dp[j][z ^ (1<<i)] + cost[i][j]);
}
}
dijkstra(n, n);
x = 1<<30;
for (i = 0; i<k; i++)
x = min(x, dp[i][(1<<k)-1] + d[c[i]]);
fout << x;
return 0;
}