Cod sursa(job #2539324)

Utilizator CharacterMeCharacter Me CharacterMe Data 5 februarie 2020 20:00:08
Problema Ubuntzei Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <bits/stdc++.h>
std::ifstream fin("ubuntzei.in");
std::ofstream fout("ubuntzei.out");
typedef long long ll;
typedef std::pair<ll, ll> pl;
ll n, m, k, ret=LLONG_MAX;
ll dist[2005][2005], list[2005], sol[20][100000];
bool check[2005], vis[2005];
std::vector<pl> graph[2005];
std::priority_queue<pl, std::vector<pl>, std::greater<pl> > pq;
void dijkstra(ll i);
int main()
{
    fin>>n>>m>>k;
    for(ll i=1; i<=k; ++i){
        fin>>list[i];
        check[list[i]]=true;
    }
    while(m--){
        ll x, y, c;
        fin>>x>>y>>c;
        graph[x].push_back({c, y});
        graph[y].push_back({c, x});
    }
    if(!k){
        dijkstra(1);
        fout<<dist[1][n];
        return 0;
    }
    for(ll i=1; i<=k; ++i) dijkstra(list[i]);
    for(ll i=1; i<=k; ++i){
        for(ll j=1; j<(1<<k); ++j) sol[i][j]=LLONG_MAX;
    }
    for(ll i=0; i<k; ++i) sol[i+1][1<<i]=dist[1][list[i+1]];
    for(ll i=1; i<(1<<k); ++i){
        ll cp=i;
        for(ll j=0; j<k; ++j){
            if(!(cp&1)){
                ll ccp=i;
                for(ll p=0; p<k; ++p){
                    if(ccp&1){
                        sol[j+1][i+(1<<j)]=std::min(sol[j+1][i+(1<<j)], sol[p+1][i]+dist[list[p+1]][list[j+1]]);
                    }
                    ccp>>=1;
                }
            }
            cp>>=1;
        }
    }
    for(ll i=1; i<=k; ++i) if(sol[i][(1<<k)-1]!=LLONG_MAX) ret=std::min(ret, sol[i][(1<<k)-1]+dist[list[i]][n]);
    fout<<ret;
    return 0;
}
void dijkstra(ll i){
    for(ll j=1; j<=n; ++j) {vis[j]=false; dist[i][j]=LLONG_MAX;}
    pq.push({0, i});
    while(!pq.empty()){
        pl now=pq.top(); pq.pop();
        if((vis[now.second] || check[now.second]) && now.second!=i) continue;
        vis[now.second]=true;
        for(auto neig:graph[now.second]){
            pl next={now.first+neig.first, neig.second};
            if(dist[i][next.second]>next.first){
                dist[i][next.second]=next.first;
                if(next.second==1 || next.second==n) dist[next.second][i]=next.first;
                pq.push(next);
            }
        }
    }
}