Pagini recente » Cod sursa (job #504027) | Cod sursa (job #722733) | Cod sursa (job #10221) | Cod sursa (job #474690) | Cod sursa (job #2981294)
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
class muchie
{
public:
int to, cost;
bool operator<(const muchie &x) const
{
return cost > x.cost;
}
};
// Variable pentru Dijkstra
int n, m, nrPrieteni, drumMinim[18][2005], noduriPrieteni[18];
vector<muchie> G[2005];
priority_queue<muchie> minHeapMuchii;
// Variable pentru ciclul Hamiltonian
int hamilton[(1 << 18)][18];
void dijkstra(int indicePrieten)
{
while (!minHeapMuchii.empty())
{
muchie curent = minHeapMuchii.top();
minHeapMuchii.pop();
if (curent.cost != drumMinim[indicePrieten][curent.to])
continue;
for (int i = 0; i < G[curent.to].size(); i++)
{
muchie vecin = G[curent.to][i], addToHeap;
addToHeap.to = vecin.to;
addToHeap.cost = curent.cost + vecin.cost;
// Cost mai bun sau nu am setat un drum prin nodul respectiv
if (addToHeap.cost < drumMinim[indicePrieten][vecin.to] || drumMinim[indicePrieten][vecin.to] == 0)
{
drumMinim[indicePrieten][vecin.to] = addToHeap.cost;
minHeapMuchii.push(addToHeap);
}
}
}
}
int main()
{
fin >> n >> m >> nrPrieteni;
for (int i = 0; i < nrPrieteni; i++)
{
int nod;
fin >> nod;
noduriPrieteni[i] = nod;
}
// 0 -> (nrPrieteni - 1) avem prieteni, nrPrieteni si (nrPrieteni + 1) sunt pentru start si finish
noduriPrieteni[nrPrieteni] = 1;
noduriPrieteni[nrPrieteni + 1] = n;
nrPrieteni += 2;
for (int i = 0; i < m; i++)
{
int from;
muchie it;
fin >> from >> it.to >> it.cost;
G[from].push_back(it);
swap(it.to, from);
G[from].push_back(it);
}
for (int i = 0; i < nrPrieteni + 2; i++)
{
int prieten = noduriPrieteni[i];
muchie it;
it.cost = 0;
it.to = prieten;
drumMinim[i][prieten] = 0;
minHeapMuchii.push(it);
dijkstra(i);
}
// Cautam lanutul Hamiltonian printre nodurile prietene
memset(hamilton, 0x3f3f3f3f, sizeof hamilton);
hamilton[1][0] = 0;
for (int config = 1; config < (1 << nrPrieteni); config++)
{
for (int pozitieBit = 0; pozitieBit < nrPrieteni; pozitieBit++)
{
// Nodul curent este in configuratie
if (config & (1 << pozitieBit))
{
for (int contorVecin = 0; contorVecin < nrPrieteni; contorVecin++)
{
// Vecinul nu poate fi nodul in care deja suntem
if (contorVecin == pozitieBit)
continue;
// Vecinul nu este prezent in configuratie
if (!(config & (1 << contorVecin)))
hamilton[config + (1 << contorVecin)][contorVecin] = min(hamilton[config + (1 << contorVecin)][contorVecin], hamilton[config][pozitieBit] + drumMinim[pozitieBit][noduriPrieteni[contorVecin]]);
}
}
}
}
fout << hamilton[(1 << nrPrieteni) - 1][nrPrieteni - 1] << "\n";
return 0;
}