Pagini recente » Cod sursa (job #1463008) | Cod sursa (job #1540662)
#include <cstdio>
#include <queue>
#include <bitset>
#include <algorithm>
#define value first
#define cost second
using namespace std;
const int INF = 1073741824;
const int DIM1 = 2048;
const int DIM2 = 18;
int nrNodes, nrEdges, nrCities, Hamilton[(1<<DIM2)][DIM2], Distance[DIM2][DIM2], D[DIM1], Cities[DIM1];
vector <pair <int, int> > Edges[DIM1]; bitset <DIM1> Marked; queue <int> Queue; int node1, node2, dist;
inline void resetValues (int startNode) {
for (int i = 0; i < nrNodes; i ++)
D[i] = INF;
while (!Queue.empty())
Queue.pop();
Marked.reset();
Queue.push(startNode);
Marked[startNode] = 1;
D[startNode] = 0;
return;
}
inline int getDistance (int startNode, int finishNode) {
resetValues (startNode);
while (!Queue.empty()) {
int node = Queue.front();
vector <pair <int, int> > :: iterator it;
for (it = Edges[node].begin(); it != Edges[node].end(); it ++) {
pair <int, int> nextNode = *it;
if (D[nextNode.value] > D[node] + nextNode.cost) {
D[nextNode.value] = D[node] + nextNode.cost;
if (!Marked[nextNode.value]) {
Marked[nextNode.value] = 1;
Queue.push(nextNode.value);
}
}
}
Marked[node] = 0;
Queue.pop();
}
return D[finishNode];
}
int main () {
freopen ("ubuntzei.in" , "r", stdin );
freopen ("ubuntzei.out", "w", stdout);
scanf ("%d", &nrNodes );
scanf ("%d", &nrEdges );
scanf ("%d", &nrCities);
Cities[0] = 0;
for (int i = 1; i <= nrCities; i ++) {
scanf ("%d", &Cities[i]);
Cities[i] --;
}
Cities[++nrCities] = nrNodes - 1;
nrCities ++;
for (int i = 1; i <= nrEdges; i ++) {
scanf ("%d %d %d", &node1, &node2, &dist);
node1 --; node2 --;
Edges[node1].push_back(make_pair(node2, dist));
Edges[node2].push_back(make_pair(node1, dist));
}
for (int i = 0 ; i < nrCities; i ++)
for (int j = i + 1; j < nrCities; j ++)
Distance[i][j] = Distance[j][i] = getDistance (Cities[i], Cities[j]);
for (int i = 0; i < (1<<nrCities); i ++)
for (int j = 0; j < nrCities; j ++)
Hamilton[i][j] = INF;
Hamilton[1][0] = 0;
for (int i = 1; i < (1<<nrCities); i ++) {
for (int j = 0; j < nrCities; j ++) {
if (!(i&(1<<j)))
continue;
for (int k = 0; k < nrCities; k ++) {
if (i&(1<<k))
continue;
if (Hamilton[i+(1<<k)][k] > Hamilton[i][j] + Distance[j][k])
Hamilton[i+(1<<k)][k] = Hamilton[i][j] + Distance[j][k];
}
}}
printf ("%d\n", Hamilton[(1<<nrCities)-1][nrCities-1]);
return 0;
}