Cod sursa(job #2481520)

Utilizator YouDontNeedMyNameJurcut Paul YouDontNeedMyName Data 27 octombrie 2019 00:20:13
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.11 kb
#include<bits/stdc++.h>
#define nmax 2001
#define kmax 17
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
int n,m,k,fr[nmax];
vector <pair<int,int> > lista[nmax];
void read(){
    in >> n >> m;
    in >> k;
    fr[0]=1;
    for(int i=1; i<=k; i++) in >> fr[i];
    for(int i=1; i<=m; i++){
        int x,y,c;
        in >> x >> y >> c;
        lista[x].push_back({y,c});
        lista[y].push_back({x,c});
    }
}
int dp[nmax][nmax];
bool cool[nmax];
priority_queue < pair<int,int> > pq;
void dijkstra(int start){
    for(int i=1; i<=n; i++) dp[start][i] = INT_MAX;
    dp[start][start]=0;
    memset(cool,0,sizeof(cool));
    pq.push({0,start});
    while(!pq.empty()){
        int node = pq.top().second;
        int dist = -pq.top().first;
        pq.pop();
        if(cool[node]) continue;
        cool[node]=1;
        for(auto x:lista[node]){
            int vecin = x.first;
            int cost = x.second;
            if(dp[start][vecin] > dist + cost){
                dp[start][vecin] = dist + cost;
                pq.push({-dp[start][vecin],vecin});
            }
        }
    }
}
int v[kmax][(1<<kmax)];
bool ap[(1<<kmax)];
void dinamica(){
    if(k==0){
        dijkstra(1);
        out << dp[1][n];
        return;
    }
    for(int i=0; i<=k; i++) dijkstra(fr[i]);
    for(int i=0; i<=k; i++){
        for(int j=0; j<(1<<(k+1)); j++){
            v[i][j]=INT_MAX;
        }
    }
    v[0][1]=0;
    for(int mask = 1; mask < (1<<(k+1)); mask++){
        for(int i=0; i<=k; i++){

            if(!(mask&(1<<i))) continue;
            if(v[i][mask] == INT_MAX)
            {
                continue;
            }
            for(int j=0; j<=k; j++){
                if((mask&(1<<j))) continue;
                v[j][(mask|(1<<j))] = min(v[j][(mask|(1<<j))], v[i][mask] + dp[fr[i]][fr[j]]);
                ap[mask|(1<<j)]=1;
            }
        }
    }
    int mi = INT_MAX;
    for(int i=1; i<=k; i++){
        mi = min(mi, v[i][(1<<(k+1))-1] + dp[fr[i]][n]);
    }
    out << mi;
}
int main()
{
    read();
    dinamica();
}