Mai intai trebuie sa te autentifici.
Cod sursa(job #1307340)
Utilizator | Data | 1 ianuarie 2015 23:13:01 | |
---|---|---|---|
Problema | Ubuntzei | Scor | 65 |
Compilator | cpp | Status | done |
Runda | Arhiva de probleme | Marime | 2.98 kb |
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int NMAX = 2000;
const int KMAX = 15;
struct drum
{
int dest;
int lung;
drum (int dest = 0, int lung = 0)
{
this->dest = dest;
this->lung = lung;
}
};
int n, m, k, tata;
int dist[KMAX + 1][NMAX + 1], oras[NMAX + 1], cost[(1 << (KMAX + 1))][NMAX + 1];
bool viz[(1 << (KMAX + 1))][NMAX + 1];
vector <drum> v[NMAX + 1];
struct cmp
{
bool operator () (const drum &a, const drum &b)
{
return a.lung > b.lung;
}
};
priority_queue <drum, vector <drum>, cmp> hp;
void dijkstra (int nod)
{
int fiu;
hp.push (drum (nod, 0));
while (!hp.empty ())
{
nod = hp.top ().dest;
hp.pop ();
for (int i = 0; i < v[nod].size (); ++i)
{
fiu = v[nod][i].dest;
if (!dist[tata][fiu] || dist[tata][fiu] > dist[tata][nod] + v[nod][i].lung)
{
dist[tata][fiu] = dist[tata][nod] + v[nod][i].lung;
hp.push (drum (fiu, dist[tata][fiu]));
}
}
}
}
struct stare
{
int st;
int ultim;
stare (int st = 0, int ultim = 0)
{
this->st = st;
this->ultim = ultim;
}
};
queue <stare> q;
void din ()
{
stare a;
for (int i = 0; i < k; ++i)
{
cost[(1 << i)][i] = dist[k][oras[i]];
viz[(1 << i)][i] = true;
q.push (stare ((1 << i), i));
}
while (!q.empty ())
{
a = q.front ();
q.pop ();
for (int i = 0; i < k; ++i)
{
if ((a.st & (1 << i)) == 0)
{
int x = a.st + (1 << i);
if (!cost[x][i] || cost[x][i] > cost[a.st][a.ultim] + dist[a.ultim][oras[i]])
{
cost[x][i] = cost[a.st][a.ultim] + dist[a.ultim][oras[i]];
if(!viz[x][i])
{
viz[x][i] = true;
q.push (stare (x, i));
}
}
}
}
viz[a.st][a.ultim] = false;
}
}
int main ()
{
freopen ("ubuntzei.in", "r", stdin);
freopen ("ubuntzei.out", "w", stdout);
int x, y, c;
scanf ("%d%d%d", &n, &m, &k);
for (int i = 0; i < k; ++i)
scanf ("%d", &oras[i]);
for (int i = 0; i < m; ++i)
{
scanf ("%d%d%d", &x, &y, &c);
v[x].push_back (drum (y, c));
v[y].push_back (drum (x, c));
}
for (int i = 0; i < k; ++i)
{
tata = i;
dijkstra (oras[i]);
}
tata = k;
dijkstra (1);
din ();
int sol = 2000000000;
if (k == 0)
sol = dist[0][n];
for (int i = 0; i < k; ++i)
if (cost[(1 << k) - 1][i] + dist[i][n] < sol)
sol = cost[(1 << k) - 1][i] + dist[i][n];
printf ("%d\n", sol);
return 0;
}