Cod sursa(job #1748888)

Utilizator DenisONIcBanu Denis Andrei DenisONIc Data 27 august 2016 09:27:10
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.82 kb
#include <fstream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#define zeros(x) ( (x ^ (x - 1)) & x )
using namespace std;

ofstream g("ubuntzei.out");

long n,k,m,v[20],x,y,uz[20],val,d,mn[2005],mat[20][20],minim,p[20],Mat[32770][17];


struct Heap{
    long nod,val;
};

vector <Heap> H[2005];
vector <Heap> Hp;

long comp(Heap a,Heap b)
{
    return a.val>b.val;
}

void mini(long poz,long nod)
{
    long lg;
    memset(mn,0,sizeof(mn));
    Heap crt;
    crt.nod = nod;
    crt.val = 0;
    Hp.push_back(crt);
    while (!Hp.empty())
    {
        nod = Hp[0].nod;
        lg = Hp[0].val;
        pop_heap(Hp.begin(),Hp.end(),comp);
        Hp.pop_back();

        for (int i=0;i<H[nod].size();i++)
        {
            if (mn[H[nod][i].nod] == 0 || mn[H[nod][i].nod]>H[nod][i].val+lg)
            {
                mn[H[nod][i].nod] = H[nod][i].val+lg;
                Heap crt;
                crt.nod = H[nod][i].nod;
                crt.val = H[nod][i].val+lg;
                Hp.push_back(crt);uz[i]=0;
                push_heap(Hp.begin(),Hp.end(),comp);
            }
        }
    }
    mat[poz][1] = mn[1];
    mat[poz][k+2] = mn[n];
    for (int i=1;i<=k;i++)
        mat[poz][i+1] = mn[v[i]];
}

void bkt(long k2)
{

    if (k2>k+1)
    {
        if (val+mat[p[k+1]][k+2]<minim || minim==-1)
            minim=val+mat[p[k+1]][k+2];
    }

    else
        for (int i=2;i<=k+1;i++)
        {
            if (uz[i]==0)
            {
                uz[i]=1;
                val = val+mat[p[k2-1]][i];
                p[k2] = i;
                if (val>=minim && minim!=-1)
                {
                    val = val-mat[p[k2-1]][i];
                    uz[i]=0;
                    return;
                }
                bkt(k2+1);
                val = val-mat[p[k2-1]][i];
                uz[i]=0;
            }
        }
}

int main()
{
    freopen("ubuntzei.in","r",stdin);
    scanf("%ld%ld",&n,&m);
    scanf("%ld",&k);

    for (int i=1;i<=k;i++)
        scanf("%ld",&v[i]);

    for (int i=1;i<=m;i++)
    {
        scanf("%ld%ld%ld",&x,&y,&d);

        Heap crt;

        crt.nod = y;
        crt.val = d;
        H[x].push_back(crt);
        crt.nod = x;
        H[y].push_back(crt);
    }

    mini(1,1);

    for (int i=1;i<=k;i++)
        mini(i+1,v[i]);

    mini(k+2,n);

    p[1] = 1;
    minim = -1;
   // bkt(2);

    if (k==0)
    {
        g<<mat[1][k+2];
        return 0;
    }

    for (int i=1;i<=(1<<(k+1))-1;i++)
    {
        for (int j=2;j<=k+1;j++)
        {
            if ((i&(1<<(j-1))) == (1<<(j-1)) && (i&1)==1)
            {
                x=-1;
                int j2 = i - (i&(1<<(j-1))),aux = j2-zeros(j2);
                if (j2==1)
                {
                    aux=j2;
                    int sav = (log2((double)zeros(aux))+1);
                    if (x==-1)
                        x = Mat[j2][sav]+mat[j][sav];
                    else
                        x = min(x,Mat[j2][sav]+mat[j][sav]);
                    aux-=zeros(aux);
                }
                else
                while (aux>0)
                {
                    int sav = (log2((double)zeros(aux))+1);
                    if (x==-1)
                        x = Mat[j2][sav]+mat[j][sav];
                    else
                        x = min(x,Mat[j2][sav]+mat[j][sav]);
                    aux-=zeros(aux);
                }
                if (x==-1)
                    x=0;
                Mat[i][j] = x;
            }
        }
    }
    //g<<minim<<"\n";
    minim = Mat[(1<<(k+1))-1][2] + mat[2][k+2];
    for (int i=2;i<=k+1;i++)
        minim = min(minim,Mat[(1<<(k+1))-1][i] + mat[i][k+2]);
    g<<minim;
    return 0;
}