Cod sursa(job #2038468)

Utilizator Andrei2000Andrei Mihailescu Andrei2000 Data 13 octombrie 2017 18:14:41
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.63 kb
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;

ifstream fin ("ubuntzei.in");
ofstream fout ("ubuntzei.out");

priority_queue<pair<int,int>>Q;
vector<pair<int,int>> G[2002];
int n,m,k,d[33000][17],dp[17][33000],v[30000],mini=inf;

void dijkstra(int inode){
    for(int i=1;i<=n;++i)dp[inode][i]=inf;
    Q.push({0,v[inode]});
    dp[inode][v[inode]]=0;
    while(!Q.empty()){
        int node=Q.top().second;
        int dist=Q.top().first;
        Q.pop();
        for(auto edge: G[node]){
            if(dp[inode][edge.first]>dist+edge.second){
                dp[inode][edge.first]=dist+edge.second;
                Q.push({dp[inode][edge.first],edge.first});
            }
        }
    }
}

int main()
{
    int a,b,c;
    fin>>n>>m>>k;
    for(int i=1;i<=k;++i)
            fin>>v[i];
    for(int i=1;i<=m;++i){
        fin>>a>>b>>c;
        G[a].push_back({b,c});
        G[b].push_back({a,c});
    }
    for(int i=1;i<=k;++i)
            dijkstra(i);
    v[0]=1;
    dijkstra(0);
    memset(d,inf,sizeof d);
    for(int msk=1;msk< (1<<k);++msk){
        if(!(msk & (msk-1))){
            for(int i=0;i<k;++i)
                if(msk==(1<<i))
                    d[msk][i]=dp[0][v[i+1]];
            continue;
        }
        for(int i=0;i<k;++i)
            for(int j=0;j<k;++j)
                if(msk&(1<<i) && msk&(1<<j))
                    d[msk][i]=min(d[msk][i],d[msk-(1<<i)][j+1]+dp[j+1][v[i+1]]);
    }
    if(!k){
        fout<<dp[0][n];
        return 0;
    }
    for(int i=0;i<k;++i)
        mini=min(mini,d[(1<<k)-1][i]+dp[i+1][n]);
    fout<<mini;
    return 0;
}