Pagini recente » Cod sursa (job #1676598) | Cod sursa (job #2005386) | Cod sursa (job #1377375) | contest_6 | Cod sursa (job #3196593)
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <cmath>
#include <unordered_map>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
const int LMAX = 2005;
const int INF = 0x3F3F3F3F;
int v[17], newgraph[17][17];
vector<pair<int, int>> L[LMAX];
vector<int> ap(LMAX, -1);
priority_queue<pair<int, int>> Q;
void dijkstra(vector<int> &dist, int source, int i) {
dist[source] = 0;
Q.push({0, source});
while (!Q.empty()) {
int node = Q.top().second, d = -Q.top().first;
Q.pop();
if (d > dist[node]) continue;
for (pair<int, int> vec : L[node]) {
if (dist[node] + vec.first < dist[vec.second]) {
dist[vec.second] = dist[node] + vec.first;
if (ap[vec.second] == -1) ///daca nodul nu apare in unul dintre cele k noduri
Q.push({-dist[vec.second], vec.second});
else {
newgraph[i][ap[vec.second]] = dist[vec.second];
newgraph[ap[vec.second]][i] = dist[vec.second];
}
}
}
}
}
void dijkstra2(vector<int> &dist, int source, int k) {
Q.push({0, source});
dist[source] = 0;
while (!Q.empty()) {
int node = Q.top().second, d = -Q.top().first;
Q.pop();
if (d > dist[node]) continue;
for (int i = 0; i < k; i++) {
if (newgraph[node][i] && dist[node] + newgraph[node][i] < dist[i]) {
dist[i] = dist[node] + newgraph[node][i];
newgraph[source][i] = dist[i];
Q.push({-dist[i], i});
}
}
}
}
int main() {
int n, m, k, i, j;
fin>>n>>m;
fin>>k;
v[0] = 0;
ap[v[0]] = 0;
for (i = 1; i <= k; i++) {
fin>>v[i];
v[i]--;
ap[v[i]] = i;
}
v[i++] = n - 1;
ap[n-1] = k + 1;
k+=2;
int x, y, c;
while (m--) {
fin>>x>>y>>c;
x--;
y--;
L[x].push_back({c, y});
L[y].push_back({c, x});
}
for (i = 0; i < k; i++) {
vector<int> dist(n, INF);
dijkstra(dist, v[i], i);
}
for (i = 0; i < k; i++) {
vector<int> dist(k, INF);
dijkstra2(dist, i, k);
}
// for (i = 0; i < k; i++) {
// fout<<i<<"--";
// for (j = 0; j < k; j++) {
// fout<<newgraph[i][j]<<" ";
// }
// fout<<endl;
// }
///acum am un graf format numai din nodurile in care vreau sa ajung si muchile dintre ele sunt de distanta minima
vector<vector<int>> dp((1<<k), vector<int>(k, INF));
dp[1][0] = 0;//incep din nodul 0
int mask;
for (mask = 3; mask < ((1<<k) - 1); mask++) {
if ((mask&1)) { //daca nodul 0 este in drum
for (i = 0; (1<<i) <= mask; i++) { //ultimul nod
if ((mask&(1<<i)) != 0) {
for (j = 0; (1<<j) <= mask; j++) {
if (i != j && (mask&(1<<j)) != 0 && newgraph[j][i]) {
dp[mask][i] = min(dp[mask][i], dp[(mask^(1<<i))][j] + newgraph[j][i]);
}
}
}
}
}
}
for (j = 0; j < k-1; j++) {
if (newgraph[j][k-1])
dp[mask][k-1] = min(dp[mask][k-1], dp[(mask^(1<<(k-1)))][j] + newgraph[j][k-1]);
}
fout<<dp[mask][k-1];
fin.close();
fout.close();
return 0;
}