Cod sursa(job #1248871)

Utilizator heracleRadu Muntean heracle Data 26 octombrie 2014 10:20:29
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.32 kb
#include <cstdio>
#include <queue>
#include <cstring>

FILE* in=fopen("ubuntzei.in","r");
FILE* out=fopen("ubuntzei.out","w");

const int Q=2009,INF=1000000007;

int nod,muc,k;
int v[20];

int d[20][20];

int m[Q][Q];

int dist[Q][Q];


int c[1<<16][20];


int inline min(const int &a, const int &b)
{
    return a<b?a:b;
}

void partea2()
{
    for(int i=0; i<=k; i++)
    {
        for(int j=0; j<=k; j++)
        {
            if(d[i][j]==0)
                d[i][j]=INF;
        }
    }

    int p2=1<<(k+1);

    for(int i=0; i<p2; i++)
    {
        for(int j=0; j<=k; j++)
        {
            c[i][j]=INF;
        }
    }

    c[1][0]=0;

    for(int i=1; i<p2/2; i++)
    {
        for(int t=0; t<=k; t++)
        {
            if((i>>t)&1==1)
            {
                for(int h=0; h<=k; h++)
                {
                    if((i>>h)&1==1 )
                        c[i][t]=min(c[i][t],c[i^(1<<t)][h]+d[h][t]);
                }
            }
        }
    }

    int re=INF;

    for(int i=0; i<k; i++)
    {
        re=min(re,c[(p2-1)^(1<<k)][i]+d[i][k]);
    }
    fprintf(out,"%d",re);

}


struct point{
    int p,val;

    bool operator <(const point &aux) const
    {
        return val>aux.val;
    }
};

std::priority_queue<point> h;

void dijkstra(int a)
{
    h.push(point{a,0});

    point act;

    while(!h.empty())
    {
        while(!h.empty() &&  dist[a][ h.top().p ]!=0  )
        {
            h.pop();
        }
        if(h.empty())
            return;

        act=h.top();

        dist[act.p][a]=act.val;
        dist[a][act.p]=act.val;
        h.pop();

        for(int i=1; i<=nod; i++)
        {
            if(m[act.p][i]!=0 && dist[a][i]==0 )
            {
                h.push({i,act.val+m[act.p][i]});
            }
        }
    }



}

int main()
{
    fscanf(in,"%d%d",&nod,&muc);

    fscanf(in,"%d",&k);

    for(int i=1; i<=k; i++)
    {
        fscanf(in,"%d",&v[i]);
    }
    v[0]=1;
    v[++k]=nod;

    int a,b,c;

    for(int i=1; i<=muc; i++)
    {
        fscanf(in,"%d%d%d",&a,&b,&c);

        m[a][b]=c;
        m[b][a]=c;
    }

    //dijkstra(nod);

    for(int i=0; i<=k; i++)
    {
        dijkstra(v[i]);
        dist[v[i]][v[i]]=0;
    }

    for(int i=0; i<=k; i++)
    {
        for(int j=0; j<=k; j++)
        {
            d[i][j]=dist[v[i]][v[j]];
        }
    }

    partea2();


    return 0;
}