Cod sursa(job #2609388)

Utilizator betybety bety bety Data 2 mai 2020 15:48:08
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <fstream>

#include <vector>

#include <set>

using namespace std;

ifstream cin("ubuntzei.in");

ofstream cout("ubuntzei.out");

const int lim=2005;

const int inf=2e9+2;

int v[lim],c[17];

vector<pair<int,int> > vec[lim];

int dist[17][lim];

int n,m,k,x,y,z;

vector<int> prez;

int dp[17][32780];

void dijkstra(int ind)

{

    set<pair<int,int> > s;

    for(int i=1;i<=n;++i)

        dist[ind][i]=inf;

    dist[ind][c[ind]]=0;

    s.insert({0,c[ind]});

    while(!s.empty())

    {

        int x=(*(s.begin())).second;

        s.erase(s.begin());

        if(dist[ind][x]==inf) continue;

        for(auto t:vec[x])

        if(dist[ind][t.first]>dist[ind][x]+t.second)

        {

            if(dist[ind][t.first]!=inf)

                s.erase(s.find({dist[ind][t.first],t.first}));

            dist[ind][t.first]=dist[ind][x]+t.second;

            s.insert({dist[ind][t.first],t.first});

        }

    }

}

int main()

{

    cin>>n>>m>>k;

    for(int i=1;i<=k;++i)

        cin>>c[i];

    for(int i=1;i<=m;++i)

    {

        cin>>x>>y>>z;

        vec[x].push_back({y,z});

        vec[y].push_back({x,z});

    }

    c[0]=1;

    for(int i=0;i<=k;++i)

        dijkstra(i);

    if(k==0)

    {
        cout<<dist[0][n]<<endl;
        return  0;
    }

    int poz=(1<<k)-1;

    for(int r=1;r<=poz;++r)

    {

        int mask=r;

        prez.clear();

        for(int i=1;i<=k and mask>0;++i)

        {

            if(mask&1) prez.push_back(i);

            mask>>=1;

        }

        if(prez.size()==1)

        {

            dp[prez[0]][r]=dist[prez[0]][1];

            continue;

        }

        for(auto i:prez)

        {

            dp[i][r]=inf;

            int look=r-(1<<(i-1));

            for(auto j:prez) if(i!=j)

            dp[i][r]=min(dp[i][r],dp[j][look]+dist[j][c[i]]);

        }

    }

    int ans=inf;

    for(int i=1;i<=k;++i)

    if(dp[i][poz]!=inf)

        ans=min(ans,dp[i][poz]+dist[i][n]);

    cout<<ans;

    return 0;

}