Cod sursa(job #3257868)

Utilizator PsyDuck1914Feraru Rares-Serban PsyDuck1914 Data 19 noiembrie 2024 18:43:10
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f ("ubuntzei.in");
ofstream g ("ubuntzei.out");

int n, m, k;

const int KMAX = 16;
const int NMAX = 2000;
const long long COSTMAX = 2e9;

vector<pair<int, int>> adj[NMAX];
vector<int> p;

bool frecv[NMAX];

priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

int dist[KMAX + 1][NMAX];
int dp[(1 << KMAX)][KMAX];

void precalcul(){
    
    for(int i=0; i<KMAX; i++)
        for(int j=0; j<NMAX; j++)
            dist[i][j] = COSTMAX;
    
}

void dijkstra(int i, int src){
    
    dist[i][src] = 0;
    
    while(!pq.empty())
        pq.pop();
        
    pq.push({0, src});
    
    while(!pq.empty()){
        
        int fromnod = pq.top().second;
        int fromcost = pq.top().first;
        
        pq.pop();
        
        if(fromcost > dist[i][fromnod])
            continue;
        
        for(auto next : adj[fromnod]){
            
            int tonod = next.first;
            int tocost = next.second;
            
            if(dist[i][tonod] > dist[i][fromnod] + tocost){
                
                dist[i][tonod] = dist[i][fromnod] + tocost;
                
                //cout << fromnod << ' ' << tonod << ' ' << dist[src][fromnod] << ' ' << tocost << endl;
                
                pq.push({dist[i][tonod], tonod});
                
            }
            
        }
        
    }

    
}

int main()
{
    
    precalcul();
    
    f >> n >> m >> k;
    
    p.push_back(0);
    
    for(int i=1; i<=k; i++){
        
        int a;
        f >> a;
        
        a -= 1;
        
        p.push_back(a);
        frecv[a] = true;
        
    }
    
    //cout << p.size() << endl;
    
    for(int i=1; i<=m; i++){
        
        int x, y, cost;
        f >> x >> y >> cost;
        
        x -= 1;
        y -= 1;
        
        adj[x].push_back({y, cost});
        adj[y].push_back({x, cost});
        
    }
    
    //dijkstra(0);
    
    if(k == 0){
        
        dijkstra(0, 0);
        g << dist[0][n-1];
        
        return 0;
        
    }
    
    for(int i=0; i<p.size(); i++)
        dijkstra(i, p[i]);
        
        
    for(int i=0; i<p.size(); i++)
        for(int j=0; j < (1 << p.size()); j++)
            dp[j][i] = COSTMAX;
    
    
    dp[1][0] = 0;
    
    for(int config = 0; config < (1 << p.size()); config++){
        
        for(int i=0; i<p.size(); i++){
            
            if(dp[config][i] != COSTMAX and (config & (1 << i)) != 0){
                
                for(int j=0; j<p.size(); j++){
                    
                    if((config & (1 << j)) == 0){
                        
                        dp[config | (1 << j)][j] = min(dp[config | (1 << j)][j], dp[config][i] + dist[i][p[j]]);
                        
                    }
                    
                }
                
            }
            
            
        }
        
    }
    
    int mn = COSTMAX;
    
    for(int i=1; i<p.size(); i++)
        mn = min(mn, dp[(1 << p.size()) - 1][i] + dist[i][n-1]);
        // cout << dist[i][n-1] << endl;
        
    //cout << dist[1][3];
        
    g << mn;

    return 0;
}