Cod sursa(job #2481301)

Utilizator YouDontNeedMyNameJurcut Paul YouDontNeedMyName Data 26 octombrie 2019 18:34:43
Problema Ubuntzei Scor 55
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <bits/stdc++.h>
#define nmax 2005
#define smax 32770
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
int n,m,k,prt[nmax],dp[nmax][nmax];
bool processed[nmax];
vector <pair<int,int> > lista[nmax];
void read(){
    in >> n >> m;
    in >> k;
    prt[0]=1;
    prt[k+1]=n;
    for(int i=1; i<=k; i++){
        in >> prt[i];
    }
    for(int i=1; i<=m; i++){
        int x,y,cost;
        in >> x >> y >> cost;
        lista[x].push_back({y,cost});
        lista[y].push_back({x,cost});
    }
}
priority_queue < pair<int,int> > pq;
void dijkstra(int node){
    for(int i=1; i<=n; i++){
        dp[node][i]=INT_MAX;
    }
    dp[node][node]=0;
    pq.push({0,node});
    memset(processed,0,sizeof(processed));
    while(!pq.empty()){
        int nod = pq.top().second;
        int dist = -pq.top().first;
        pq.pop();
        if(processed[nod]) continue;
        processed[nod]=1;
        for(auto x:lista[nod]){
            int vecin = x.first;
            int cost = x.second;
            if(dp[node][vecin] > cost + dist){
                dp[node][vecin] = cost + dist;
                pq.push({-dp[node][vecin],vecin});
            }
        }
    }
}
void precalc()
{
    for(int i=0; i<=k+1; i++)
        dijkstra(prt[i]);
}
bool done[17][(1<<17)];
int v[17][(1<<17)];
priority_queue <pair<int,pair<int,int> > > q;
void dijkstra2(){
    for(int i=0; i<=k+1; i++){
        for(int j=0; j<(1<<(k+1)); j++){
            v[i][j]=INT_MAX;
        }
    }
    for(int i=1; i<=k; i++){
        v[i][(1<<(i-1))] = dp[1][prt[i]];
        q.push({-dp[1][prt[i]],{i,(1<<(i-1))}});
    }
    while(!q.empty()){
        int val = -q.top().first;
        int node = q.top().second.first;
        int masca = q.top().second.second;
        q.pop();
        if(done[node][masca]) continue;
        done[node][masca]=1;
        for(int i=1; i<=k; i++){
            if(i==node) continue;
            int masca_noua = (masca|(1<<(i-1)));
            if(v[i][masca_noua] > val+dp[prt[node]][prt[i]]){
                v[i][masca_noua] = val+dp[prt[node]][prt[i]];
                q.push({-v[i][masca_noua],{i,masca_noua}});
            }
        }
    }
    int mi = INT_MAX;
    for(int i=1; i<=k; i++){
        mi = min(mi,v[i][(1<<k)-1]+dp[prt[i]][n]);
    }
    out << mi;
}
int main()
{
    read();
    precalc();
    dijkstra2();
}