Mai intai trebuie sa te autentifici.
Cod sursa(job #2990894)
Utilizator | Data | 8 martie 2023 18:58:59 | |
---|---|---|---|
Problema | Ubuntzei | Scor | 100 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva de probleme | Marime | 2.33 kb |
#include <bits/stdc++.h>
using namespace std;
const int nmax = 2e3;
const int kmax = 15;
const int inf = 2e9 + 5;
vector<vector<pair<int, int>>> dx(nmax+5);
int n, m, k, v[kmax+5], dist[nmax+5][nmax+5], temp[nmax+5];
int dp[(1<<kmax)][kmax];
// dp[mask][i] - went through all nodes in mask and are in node i
void dijkstra(int start) {
priority_queue< pair<int, int>,
vector<pair<int, int>>,
greater<pair<int, int>>> pq;
for(int i=1; i<=n; i++) temp[i] = inf;
temp[start] = 0;
pq.emplace(0, start);
while(pq.empty() == false) {
pair<int, int> now = pq.top(); pq.pop();
if(temp[now.second] != now.first) continue;
for(auto edge : dx[now.second])
if(temp[edge.second] > temp[now.second] + edge.first) {
temp[edge.second] = temp[now.second] + edge.first;
pq.emplace(temp[edge.second], edge.second);
}
}
for(int i=1; i<=n; i++) {
dist[start][i] = min(dist[start][i], temp[i]);
dist[i][start] = min(dist[i][start], temp[i]);
}
}
int main() {
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
f >> n >> m >> k;
for(int i=0; i<k; i++) f >> v[i];
for(int i=1; i<=m; i++) {
int x, y, d; f >> x >> y >> d;
dx[x].emplace_back(d, y);
dx[y].emplace_back(d, x);
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
dist[i][j] = inf;
dijkstra(1); dijkstra(n);
for(int i=0; i<k; i++) dijkstra(v[i]);
for(int mask=0; mask<(1<<k); mask++)
for(int i=0; i<k; i++)
dp[mask][i] = inf;
for(int i=0; i<k; i++)
dp[(1<<i)][i] = dist[1][v[i]];
for(int mask=0; mask<(1<<k); mask++)
for(int node=0; node<k; node++) {
if(((1<<node) & mask) == 0) continue;
for(int next=0; next<k; next++) {
if(next == node or ((1<<next) & mask)) continue;
int newmask = mask + (1<<next);
int cost = dist[v[node]][v[next]];
dp[newmask][next] = min(dp[newmask][next], dp[mask][node] + cost);
}
}
if(k == 0) {
g << dist[1][n];
return 0;
}
int ans = inf;
for(int i=0; i<k; i++) ans = min(ans, dp[(1<<k)-1][i] + dist[v[i]][n]);
g << ans;
return 0;
}