Pagini recente » Cod sursa (job #2105406) | Cod sursa (job #229247) | Cod sursa (job #2222472) | Cod sursa (job #2436095) | Cod sursa (job #637597)
Cod sursa(job #637597)
// priority_queue<T, vector<T>, greater<T> > heap;
/*lant hamiltonian pe graf format numai din nodurile cu prieteni si 1 si n, cu muchii egale cu distantele dintre
ele preprocesate cu dijkstra
+
dinamica [submultime][nod_final_submultime] -> dinamica[submultime + nod_nou][nod_nou]
pt fiecare submultime de elem conteaza numai costul minim dintre ele (costurile pt drumurile dintre celelalte noduri
nu depind de cele existente in submultime)
*/
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
const int INF = 1000000000;
const int N = 2012;
const int K = 17;
struct destinatie
{
int dest,cost;
};
priority_queue < pair <int,int>, vector < pair<int,int> >, greater< pair<int,int> > > heap;
vector< destinatie > vecin[N]; int n; int d[N];
int noduri_k[K],k;
int a[1<<(K-2)][K]; //dinamica pe submultimi si elem final din submultime
int graf[K][K];
void citire()
{
int m;
int a,b,c;
scanf("%d%d",&n,&m);
scanf("%d",&k);
noduri_k[0] = 1;
for (int i = 1;i <= k; ++i)
scanf("%d",&noduri_k[i]);
noduri_k[k+1] = n;
for (int i = 1; i <= m; ++i)
{
scanf("%d%d%d",&a,&b,&c);
vecin[a].push_back((destinatie){b,c});
vecin[b].push_back((destinatie){a,c});
}
}
void init_dijkstra()
{
for (int i = 1; i <= n; ++i)
d[i] = INF;
}
void dijkstra(int nod_start)
{
int nod,c;
init_dijkstra();
heap.push(make_pair(0,nod_start));
while (!heap.empty())
{
nod = heap.top().second;
c = heap.top().first;
heap.pop();
if (d[nod] != INF)
continue;
d[nod] = c;
for (unsigned int i = 0; i < vecin[nod].size(); ++i)
if (d[vecin[nod][i].dest] == INF)
heap.push(make_pair(c+vecin[nod][i].cost,vecin[nod][i].dest));
}
}
void dinamica() //identific submultime prin cifrele in baza 2 ale indicelui, cifra 0 indica daca exista nodul k 1, 1 nodul k 2 ...
{
int in,jn;
for (int i = 1; i <= (1<<k) - 1; ++i)
for (int j = 0; j <= k-1; ++j)
{
if ((i & (1<<j)) == 0) //i & (1<<j) == 1<<j daca contine cifra
continue;
if ((i & (i-1)) == 0)
{
a[i][j] = graf[0][j+1];
continue;
}
//elimin ultimul nod din config (nodul j) si dau for pt cine a fost ultimul nod
in = i - (1<<j);
a[i][j] = INF;
for (jn = 0; jn <= k-1; ++jn)
if ((in & (1<<jn)) != 0)
a[i][j] = min(a[i][j],a[in][jn] + graf[jn+1][j+1]);
}
int rasp = INF;
for (int j = 0; j <= k-1; ++j)
rasp = min(rasp,a[(1<<k) - 1][j] + graf[j+1][k+1]);
printf("%d\n",rasp);
}
int main()
{
freopen("ubuntzei.in","r",stdin);
freopen("ubuntzei.out","w",stdout);
citire();
for (int i = 0; i <= k+1; ++i)
{
dijkstra(noduri_k[i]);
for (int j = 0; j <= k+1; ++j)
graf[i][j] = d[noduri_k[j]];
}
dinamica();
return 0;
}