Cod sursa(job #2542050)

Utilizator StanCatalinStanCatalin StanCatalin Data 9 februarie 2020 13:40:51
Problema Ubuntzei Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <iostream>
#include <fstream>

using namespace std;

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

const int dim = 2005;
const int M = 10005;
const int INF = 1e9;

int nr,vf[2*M],lst[2*M],urm[2*M],n,m,k,cst[2*M],st,dr,q[dim+1],d[dim][20],inq[dim];
int val[20];

int dp[(1<<18)][20];

void Adauga(int x,int y,int c)
{
    vf[++nr] = y;
    cst[nr] = c;
    urm[nr] = lst[x];
    lst[x] = nr;
}

void inc(int &x)
{
    x++;
    if (x == dim+1)
        x = 0;
}

void bf(int nod,int care)
{
    ///cout << nod << " ";
    st = 0;
    dr = -1;
    d[nod][care] = 0;
    inc(dr);
    q[dr] = nod;
    inq[nod] = 1;
    int x,y,c;
    while (dr != st-1)
    {
        x = q[st];
        inc(st);
        inq[x] = 0;
        for (int p=lst[x]; p!=0; p = urm[p])
        {
            y = vf[p];
            ///   cout << y << " - " << d[y][care] << "\n";
            c = cst[p];

            if (d[x][care] + c < d[y][care])
            {
                d[y][care] = d[x][care] + c;
                if (!inq[y])
                {
                    inc(dr);
                    q[dr] = y;
                    inq[y] = 1;
                }
            }
        }
    }
}

int main()
{
    in >> n >> m;
    in >> k;
    for (int i=1; i<=n; i++)
    {
        for (int j=0; j<=k; j++)
        {
            d[i][j] = INF;
        }
    }
    for (int i=1; i<=k; i++)
    {
        in >> val[i];
    }
    for (int i=1,x,y,c; i<=m; i++)
    {
        in >> x >> y >> c;
        Adauga(x,y,c);
        Adauga(y,x,c);
    }
    if (k == 0)
    {
        bf(1,0);
        out << d[n][0];
        return 0;
    }
    for (int i=1; i<=k; i++)
    {
        bf(val[i], i);
    }

    for (int i=0; i<=(1<<k) - 1; i++)
    {
        for (int j=0; j<=k; j++)
        {
            dp[i][j] = INF;
        }
    }
    dp[0][0] = 0;
    for (int i=1; i<=k; i++)
    {
        dp[(1<<(i-1))][i] = d[1][i];
    }
    for (int bitmask = 1; bitmask <= (1<<k) - 1; bitmask++)
    {
        for (int j=1; j<=k; j++)
        {
            if (bitmask&(1<<(j-1)) != 0)
            {
                int mask = bitmask - (1<<(j-1));
                for (int p=1; p<=k; p++)
                {
                   /// if (bitmask == 3 && j == 1 && p == 2) cout << (mask&(1<<(p-1)));
                    if ((mask&(1<<(p-1))) != 0)
                    {

                        ///if (bitmask == 3 && j == 1) cout << mask << " ";
                        dp[bitmask][j] = min(dp[bitmask][j], dp[mask][p] + d[val[j]][p]);
                    }
                }
            }
        }
    }
   /// cout << dp[3][2];
    int rasp = 1e9;
    for (int i=1; i<=k; i++)
    {
        rasp = min(rasp, dp[(1<<(k)) - 1][i] + d[n][i]);
    }
    out << rasp;

    return 0;
}