Cod sursa(job #2061452)

Utilizator KOzarmOvidiu Badea KOzarm Data 9 noiembrie 2017 11:57:38
Problema Ubuntzei Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.99 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[10003];

int ubz[18][18],d[131073][2003];
int k,kk,u[18],n,m;
bool viz[2003],vizi[131073][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]);
        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();
        viz[nd.x]=1;
        int act=getUbunt(nd.x);
        if(act!=-1)
        {
            ubz[i][act]=cost;
            ubz[act][i]=cost;
        }
        for(vector <nod>::iterator it=G[poz].begin();it!=G[poz].end();it++)
        if(viz[it->x]==0)
        {
            nd1.x=it->x;
            nd1.cost=nd.cost+it->cost;
            adauga(nd1);
        }
    }
}

void dfs(int poz)
{
    int stare=1;
    nd.x=poz;
    nd.cost=stare;
    sol.push(nd);
    while(!sol.empty())
    {
        nd=sol.front();
        sol.pop();
        vizi[nd.cost][nd.x]=0;

        for(vector <nod>::iterator it=G[nd.x].begin();it!=G[nd.x].end();it++)
        {
            int act=getUbunt(it->x);
            if(act!=-1)
                nd1.cost=(nd.cost|(1<<act-1));
            else
                nd1.cost=nd.cost;
            if(d[nd1.cost][it->x]>d[nd.cost][nd.x]+it->cost)
            {
                d[nd1.cost][it->x]=d[nd.cost][nd.x]+it->cost;
                if(vizi[nd1.cost][it->x]==0)
                {
                    nd1.x=it->x;
                    sol.push(nd1);
                    vizi[nd1.cost][nd1.x]=1;
                }
            }
        }
    }
}


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++)
        getMin(u[i],i,0);

    for(int i=1;i<=(1<<n)-1;i++)
    for(int j=1;j<=n;j++)
        d[i][j]=2000000000;
    d[1][1]=0;
    dfs(1);

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