Pagini recente » Cod sursa (job #2151547) | Cod sursa (job #1078992) | Cod sursa (job #1625204) | Cod sursa (job #2763617) | Cod sursa (job #1638986)
#include <iostream>
#include <fstream>
#include <vector>
#include <utility>
#include <queue>
#define INF ( (1 << 30) - 1)
#define NMAX 2005
using namespace std;
vector < pair < int, int> > G[NMAX]; //Graful memorat prin liste de adiacenta. second = costul
vector<int>k; //Vectorul ce contine toti ubuntzeii, + nodul 1 si nodul N
vector<int> dist[NMAX]; //Vectorul cu distante. Se va calcula doar pentru nodul 1 si ubuntzei
vector<int> D[18]; //D[ultNod][conf] = costul drumului pana la ultNod, drum ce contine
int N, M, K; //nodurile din configuratie
void initializare();
void bellmanFord(int nodStart);
int memoizare(int nod, int conf);
int main()
{
initializare();
for(int i=0; i<k.size()-1; ++i) //BellmanFord-ul se face pentru toate nodurile din vector, exceptie nodul N
bellmanFord(k[i]);
for(int i=0; i<=K+2; ++i)
D[i].assign(1<<(K+3), INF); //Initializarea costurilor drumurilor
cout<<memoizare(k.size()-1, (1<<K)-1)<<'\n'; //Rezultatul se afla in D[K+1][111...11]. Mai exact drumul se termina cu
return 0; //nodul N si contine toate elementele din vectorul cu ubuntzei.
}
int memoizare(int ultNod, int conf) //IMPORTANT: Configurtia nu contine ultimul nod niciodata
{
if(D[ultNod][conf] < INF) //Daca s-a calculat deja
return D[ultNod][conf];
if(conf == 0) //Daca drumul nu are nici un nod
return dist[1][k[ultNod]]; //Se returneaza costul de la nodul 1 la nodul ultNod
for(int i=1; i<=K; ++i) //Se incearca imbunatatirea unei muchii (ubuntzei, ultNod)
{
int val = INF;
if((conf<<(i-1)) & 1) { //Configuratie actuala contine al i-lea ubuntzei
val = memoizare(i, conf - (1<<(i-1))); //Se considera ultimul nod i, configuratia necontinandu-l inca
val += dist[i][k[ultNod]]; //Costului drumului pana la i se adauga dist de la i la ultimul nod
}
if(val < D[ultNod][conf]) //Se doreste obtinerea minimului
D[ultNod][conf] = val;
}
return D[ultNod][conf];
}
void bellmanFord(int nodStart)
{
int nod, vec, d, dvec;
queue<int>Q;
vector<bool>inQueue;
inQueue.assign(N+2, 0);
dist[nodStart].assign(N+2, INF);
dist[nodStart][nodStart] = 0;
Q.push(nodStart);
while(!Q.empty())
{
nod = Q.front();
Q.pop();
d = dist[nodStart][nod];
for(int i=0; i<G[nod].size(); ++i)
{
vec = G[nod][i].first;
dvec = G[nod][i].second;
if(d + dvec < dist[nodStart][vec]) {
dist[nodStart][vec] = d + dvec;
if(!inQueue[vec])
Q.push(vec);
}
}
}
}
void initializare()
{
freopen("ubuntzei.in", "rt", stdin);
freopen("ubuntzei.out", "wt", stdout);
int ubu, x, y, c;
scanf("%d%d%d", &N, &M, &K);
k.push_back(1);
for(int i=1; i<=K; ++i) {
scanf("%d", &ubu);
k.push_back(ubu);
}
k.push_back(N);
for(int i=1; i<=M; ++i) {
scanf("%d%d%d", &x, &y, &c);
G[x].push_back(make_pair(y, c));
G[y].push_back(make_pair(x, c));
}
}