Pagini recente » Cod sursa (job #1557048) | Statistici Nunum nunum (Nunum) | Cod sursa (job #1407543) | Cod sursa (job #1531690) | Cod sursa (job #2297804)
/*
* Giving the Linus Torvalds Award to the Free Software Foundation
* is a bit like giving the Han Solo Award to the Rebel Alliance.
* - Richard M. Stallman
*/
#include <fstream>
#include <vector>
#include <queue>
#include <memory>
const int INF = 1 << 28;
const int MAX_K = 17;
struct Edge
{
int from, to;
int cost;
};
std::unique_ptr<std::vector<int>> dijkstra(const std::vector<std::vector<Edge>> &graph, int nNodes, int startNode)
{
std::unique_ptr<std::vector<int>> result{new std::vector<int>};
std::vector<int> &distances = *result;
std::vector<bool> was;
std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> pq;
distances.insert(distances.begin(), static_cast<unsigned long>(nNodes), INF);
was.insert(was.begin(), static_cast<unsigned long>(nNodes), false);
distances[startNode] = 0;
pq.push({distances[startNode], startNode});
while(!pq.empty())
{
while(!pq.empty() && was[pq.top().second])
pq.pop();
if(!pq.empty())
{
int x = pq.top().second;
pq.pop();
for(auto edge: graph[x])
{
if(distances[x] + edge.cost < distances[edge.to])
{
distances[edge.to] = distances[x] + edge.cost;
pq.push({distances[edge.to], edge.to});
}
}
}
}
return result;
}
int cost[MAX_K][MAX_K];
int d[1 << MAX_K][MAX_K];
int main()
{
std::ifstream fin("ubuntzei.in");
int n, m, k;
std::vector<int> pointsOfInterest;
std::vector<std::vector<Edge>> graph;
fin >> n >> m >> k;
pointsOfInterest.insert(pointsOfInterest.begin(), static_cast<unsigned long>(k + 2), {});
pointsOfInterest[0] = 0;
pointsOfInterest[k + 1] = n - 1;
for(int i = 1; i <= k; i++)
fin >> pointsOfInterest[i], pointsOfInterest[i]--;
graph.insert(graph.begin(), static_cast<unsigned long>(n), {});
for(int i = 0; i < m; i++)
{
int x, y, z;
fin >> x >> y >> z;
x--; y --;
graph[x].push_back({x, y, z});
graph[y].push_back({y, x, z});
}
for(int i = 0; i < k + 2; i++)
for(int j = 0; j < k + 2; j++)
cost[i][j] = i == j ? 0 : INF;
for(int i = 0; i < pointsOfInterest.size(); i++)
{
auto d = dijkstra(graph, n, pointsOfInterest[i]);
for(int j = 0; j < pointsOfInterest.size(); j++)
cost[i][j] = (*d)[pointsOfInterest[j]];
}
int nn = k + 2;
for(int i = 0; i < (1 << nn); i++)
for(int j = 0; j < nn; j++)
d[i][j] = INF;
d[1][0] = 0;
for(int i = 3; i < (1 << nn); i += 2)
for(int j = 0; j < nn; j++)
for(int k = 0; k < nn; k++)
if(((1 << k) & i) != 0 && k != j)
{
d[i][j] = std::min(d[i][j], d[i ^ (1 << j)][k] + cost[k][j]);
}
std::ofstream fout("ubuntzei.out");
int r = INF;
for(int i = 0; i < nn; i++)
r = std::min(r, d[(1 << nn) - 1][i]);
fout << r;
return 0;
}