Cod sursa(job #2575356)

Utilizator Robys01Robert Sorete Robys01 Data 6 martie 2020 13:03:09
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <bits/stdc++.h>
#define INF (1<<30)
#define PII pair <int, int>
#define Nod second
#define Cost first
using namespace std;

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

int n, m, nr, vf[20001], urm[20001], last[2001], cost[20001];
int k, loc[18], dist[2001], distL[18][18], dp[18][1<<18];
priority_queue < PII, vector < PII >, greater < PII > > Q;
bitset < 2001 > viz;

void adauga(int from, int to, int price)
{
    vf[++nr] = to;
    urm[nr] = last[from];
    last[from] = nr;
    cost[nr] = price;
}

void citire()
{
    fin>>n>>m>>k;
    for(int i = 1; i<=k; i++)
        fin>>loc[i+1];
    loc[1] = 1; loc[k+2] = n;
    k+=2;

    for(int x, y, c, i = 1; i<=m; i++)
    {
        fin>>x>>y>>c;
        adauga(x, y, c);
        adauga(y, x, c);
    }
}

void dijkstra(int x, int r)
{
    for(int i = 1; i<=n; i++)
    {
        dist[i] = INF;
        viz[i] = 0;
    }
    dist[x] = 0;
    Q.push( {0, x} );

    while(!Q.empty())
    {
        while(!Q.empty() and  viz[ Q.top().Nod ] )
            Q.pop();

        if(Q.empty())
            break;

        int nod = Q.top().Nod;
        int pret = Q.top().Cost;
        viz[nod] = 1;

        for(int k = last[nod]; k; k = urm[k])
        {
            if(!viz[ vf[k] ] and dist[ vf[k] ] > pret + cost[k]  )
            {
                dist[ vf[k] ] = pret + cost[k];
                Q.push( {dist[vf[k]], vf[k]} );
            }
        }
    }
    for(int i = 1; i<=k; i++)
        distL[r - 1][i - 1] = dist[ loc[i] ];

}


int main()
{
    citire();
    for(int i = 1; i<=k; i++)
        dijkstra(loc[i], i);

    for(int i = 0; i<(1<<k); i++)
        for(int nod = 0; nod < k; nod++)
            dp[nod][i] = INF;

    for(int i = 0; i< k; i++)
        dp[i][(1<<i)] = distL[0][i];

    for(int i = 0; i < (1<<k); i++)
        for(int nod = 0; nod < k; nod++)
            if(i & (1<<nod))
            {
                for(int vec = 0; vec < k; vec ++)
                    if(i * (1<<vec))
                        dp[nod][i] = min(dp[nod][i], dp[vec][i - (1<<nod)] + distL[vec][nod] );
            }
    int minim = INF;

    for(int i = 0; i < k; i++)
        minim = min(minim, dp[i][(1<<k) - 1] + distL[i][k - 1]);
    fout<<minim;



    return 0;
}