Pagini recente » Cod sursa (job #873430) | Cod sursa (job #1935637) | Cod sursa (job #1027168) | Cod sursa (job #2751217) | Cod sursa (job #2649677)
#include <fstream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <climits>
#define INF 1000000000000000
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int i, n, m, T, air, k, start, ending, cost, friend_location[20], j, no_Treasures, start_treasure;
long long dist[100010], stack[100010];
int isFriend[100010];
bool isNode[100010];
long long C[100025][20];
long long Cost[20][20];
vector<int> nodes;
vector<pair<int, int>> bigGraph[100001];
vector<int> smallGraph[20];
bool cmd(int a, int b) {
if (a < b)
return 1;
return 0;
}
void dijkstra(int start) {
//vector<pair<int, int>> bigGraph[10001];
long long st, dr;
bool visited[10010] = { 0 };
for (unsigned int i = 0; i < nodes.size(); i++) {
dist[nodes[i]] = INF;
}
dist[start] = 0;
stack[0] = start;
int startNodeSmall = isFriend[start];
st = dr = 0;
while (st <= dr) {
for (auto node : bigGraph[stack[st]]) {
if (!visited[node.first]) {
if (node.second + dist[stack[st]] < dist[node.first]) {
long long prev_value = dist[node.first];
dist[node.first] = node.second + dist[stack[st]];
int currentSmallNode = isFriend[node.first];
if (currentSmallNode || node.first == 0) {
if (prev_value == INF) {
smallGraph[startNodeSmall].push_back(currentSmallNode);
Cost[startNodeSmall][currentSmallNode] = dist[node.first];
}
else {
for (auto nodeToUpdate : smallGraph[startNodeSmall])
if (nodeToUpdate == currentSmallNode) {
Cost[startNodeSmall][nodeToUpdate] = dist[node.first] < Cost[startNodeSmall][nodeToUpdate] ? dist[node.first] : Cost[startNodeSmall][nodeToUpdate];
break;
}
}
}
stack[++dr] = node.first;
}
}
else {
if (node.second + dist[stack[st]] < dist[node.first]) {
long long prev_value = dist[node.first];
dist[node.first] = node.second + dist[stack[st]];
int currentSmallNode = isFriend[node.first];
if (currentSmallNode || node.first == 0) {
if (prev_value == INF) {
smallGraph[startNodeSmall].push_back(currentSmallNode);
Cost[startNodeSmall][currentSmallNode] = dist[node.first];
}
else {
for (auto nodeToUpdate : smallGraph[startNodeSmall])
if (nodeToUpdate == currentSmallNode) {
Cost[startNodeSmall][nodeToUpdate] = dist[node.first] < Cost[startNodeSmall][nodeToUpdate] ? dist[node.first] : Cost[startNodeSmall][nodeToUpdate];
break;
}
}
}
}
}
}
visited[stack[st]] = 1;
st++;
}
//sort(smallGraph[isTreasure[start]].begin(), smallGraph[isTreasure[start]].end(), cmd);
}
void HamiltonianCicle() {
no_Treasures+=2;
int pow2 = 1 << no_Treasures;
for (int i = 0; i < pow2; ++i) {
for (int j = 0; j < no_Treasures; ++j) {
C[i][j] = INF;
}
}
C[1][0] = 0;
for (int i = 0; i < pow2; i++) {
for (int j = no_Treasures - 1; j >= 0; --j) {
if (i & (1 << j)) {
for (size_t k = 0; k < smallGraph[j].size(); ++k) {
if (i & (1 << smallGraph[j][k])) {
C[i][j] = min(C[i][j], 1LL * C[i ^ (1 << j)][smallGraph[j][k]] + Cost[smallGraph[j][k]][j]);
}
C[i][j] = min(C[i][j], 1LL * C[i][smallGraph[j][k]] + Cost[smallGraph[j][k]][j]);
}
}
}
}
}
int main() {
fin >> n >> m;
fin >> no_Treasures;
start_treasure = 0;
for (i = 0; i < no_Treasures; i++) {
fin >> friend_location[i];
friend_location[i]--;
isFriend[friend_location[i]] = i + 1;
}
isFriend[n - 1] = i + 1;
for (i = 0; i < m; i++) {
fin >> start >> ending >> cost;
start--;
ending--;
bigGraph[start].push_back(make_pair(ending, cost));
bigGraph[ending].push_back(make_pair(start, cost));
if (!isNode[start])
nodes.push_back(start), isNode[start] = 1;
if (!isNode[ending])
nodes.push_back(ending), isNode[ending] = 1;
}
isFriend[0] = 0;
for (i = 0; i <= 14; i++)
for (j = 0; j <= 14; j++)
Cost[i][j] = INF;
dijkstra(0);
for (i = 0; i < no_Treasures; i++) {
dijkstra(friend_location[i]);
}
dijkstra(n-1);
HamiltonianCicle();
fout << C[(1 << no_Treasures) - 1][isFriend[n - 1]];
}