Pagini recente » Cod sursa (job #3228544) | Cod sursa (job #549992) | Cod sursa (job #738151) | Cod sursa (job #2625972) | Cod sursa (job #1586110)
#define DEBUG
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 2005;
const int MAXK = 17;
const int INF = 1 << 30;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
int n;
vector<int> vecini[MAXN];
vector<int> cost[MAXN];
int special[MAXK];
int d[MAXN][MAXN];
int e[MAXK][1 << MAXK];
int k;
void citire()
{
int m;
in >> n >> m;
in >> k;
for (int i = 1;i <= k;++i)
in >> special[i];
for (int i = 1;i <= m;++i)
{
int x,y,c;
in >> x >> y >> c;
vecini[x].push_back(y);
cost[x].push_back(c);
vecini[y].push_back(x);
cost[y].push_back(c);
}
}
void dijkstra(int s)
{
//initializare
for (int i = 1;i <= n;++i)
d[s][i] = INF;
priority_queue< pair<int,int>,vector< pair<int,int> >, greater< pair<int,int> > > heap;
heap.push(make_pair(0,s));
while(!heap.empty())
{
int nod = heap.top().second;
int c = heap.top().first;
heap.pop();
if (d[s][nod] != INF)
continue;
d[s][nod] = c;
for (unsigned int i = 0;i < vecini[nod].size();++i)
heap.push(make_pair(d[s][nod] + cost[nod][i],
vecini[nod][i]));
}
}
void calculare_distante()
{
//calculare d
dijkstra(1);
dijkstra(n);
for (int i = 1;i <= k;++i)
dijkstra(special[i]);
}
int S;
int sol[MAXK];
int nrbiti(int nr)
{
int rasp = 0;
while(nr != 0)
{
if ((nr & 1) != 0)
++rasp;
nr >>= 1;
}
return rasp;
}
void prelucrare()
{
if (nrbiti(S) == 1)
return;
for (int u = 1;u <= k;++u)
{
e[u][S] = INF;
if ((S & (1 << u)) == 0)
continue;
for (int v = 1;v <= k;++v)
if(v != u && (S & (1 << v)) != 0)
{
int nr = e[v][S - (1 << u)] + d[special[v]][special[u]];
if (nr < e[u][S])
e[u][S] = nr;
}
}
}
void dinamica()
{
//initializare
for (int i = 1;i <= k;++i)
e[i][1 << i] = d[1][special[i]];
for (int s = 1;s < (1 << k);++s)
{
S = s << 1;
prelucrare();
}
}
void afisare()
{
if (k == 0)
{
out << d[1][n] << '\n';
return;
}
S = ((1 << k) - 1) << 1;
int raspuns = INF;
for (int u = 1;u <= k;++u)
{
int nr = e[u][S] + d[u][n];
if (nr < raspuns)
raspuns = nr;
}
out << raspuns << '\n';
}
int main()
{
citire();
calculare_distante();
#ifdef DEBUG
for (int i = 1;i <= n;++i)
printf("%u ",vecini[i].size());
printf("\n\n");
for (int i = 1;i <= n;++i)
{
for (int j = 1;j <= n;++j)
printf("%d ",d[i][j]);
printf("\n");
}
#endif // DEBUG
dinamica();
afisare();
return 0;
}