Cod sursa(job #2062292)

Utilizator KOzarmOvidiu Badea KOzarm Data 10 noiembrie 2017 10:40:37
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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


struct nod
{
    int x,cost;
}nd,nd1,hp[100003];

int ubz[18][18],d[131073][18];
int k,kk,u[18],n,m;
bool viz[2003];

vector <nod> G[2005];
queue <nod> sol;
int getUbunt(int poz)
{
    for(int i=1;i<=k;i++)
    if(poz==u[i])
        return i;
    return -1;
}


void adauga(nod nd)
{
    kk++;
    hp[kk]=nd;
    int poz=kk;
    while(poz/2>0&&hp[poz/2].cost>hp[poz].cost)
    {
        swap(hp[poz],hp[poz/2]);
        poz/=2;
    }
}


void scoate()
{
    hp[1]=hp[kk];
    int poz=1;
    kk--;
    while(poz<=kk)
    {
        int fiu;
        if(2*poz>kk)
            return;
        else
        if(2*poz+1>kk)
            fiu=2*poz;
        else
        {
            if(hp[2*poz+1].cost>hp[2*poz].cost)
                fiu=2*poz;
            else
                fiu=2*poz+1;
        }
        if(hp[poz].cost>hp[fiu].cost)
        {
            swap(hp[poz],hp[fiu]);
            poz=fiu;
        }
        else
            return;
    }
}




void getMin(int poz,int i,int cost)
{
    nd.cost=0;
    nd.x=poz;
    adauga(nd);
    while(kk>0)
    {
        nd=hp[1];
        scoate();
        if(viz[nd.x]==0)
        {
            viz[nd.x]=1;
            int act=getUbunt(nd.x);
            if(act!=-1)
            {
                ubz[i][act]=nd.cost;
                ubz[act][i]=nd.cost;
            }
            for(vector <nod>::iterator it=G[nd.x].begin();it!=G[nd.x].end();it++)
            if(viz[it->x]==0)
            {
                nd1.x=it->x;
                nd1.cost=nd.cost+it->cost;
                adauga(nd1);
            }
        }
    }
}



int main()
{
    fin>>n>>m;
    fin>>k;
    k+=2;
    for(int i=2;i<k;i++)
        fin>>u[i];
    u[1]=1;
    u[k]=n;
    for(int i=1;i<=m;i++)
    {
        int x,y,c;
        fin>>x>>y>>c;
        nd.x=x;
        nd.cost=c;
        G[y].push_back(nd);
        nd.x=y;
        G[x].push_back(nd);
    }
    for(int i=1;i<=k;i++)
    {
        for(int j=1;j<=n;j++)
            viz[j]=0;
        getMin(u[i],i,0);
    }
    for(int i=1;i<=(1<<k)-1;i++)
    for(int j=1;j<=k;j++)
        d[i][j]=2000000000;
    d[1][1]=0;


    for(int i=1;i<=(1<<k)-1;i++)
    for(int j=1;j<=k;j++)
    {
        int poz=i^(1<<(j-1));
        if(poz<i&&poz>0)
        {
            for(int q=0;(1<<q)<=i;q++)
            if((i&(1<<q))>0)
            {
                    d[i][j]=min(d[i][j],d[poz][q+1]+ubz[q+1][j]);
            }
        }
    }


    fout<<d[(1<<k)-1][k];
    return 0;
}