Cod sursa(job #900002)

Utilizator ard_procesoareLupicu ard_procesoare Data 28 februarie 2013 17:16:58
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <fstream>
#include <vector>
#include <queue>
#define NMAX 2005
#define pb push_back
#define INF 2000000000
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
vector <int> v[NMAX],cost[NMAX];
int cost2[20][20],n,m,k,ck[20],verif;
int viz[NMAX],in[NMAX],drum[NMAX],d[66000][20],last[20];
void read()
{
    int a,b,c;
    fin>>n>>m>>k;
    ck[0]=1;
    for(int i=1;i<=k;i++)
        fin>>ck[i];
    for(int i=1;i<=m;i++)
    {
        fin>>a>>b>>c;
        v[a].pb(b);
        v[b].pb(a);
        cost[a].pb(c);
        cost[b].pb(c);
    }
}
void bford(int val)
{
    int nod,dist;
    nod = val;
    queue <int> qnod;
    verif ++ ;
    viz[nod] = verif ;
    drum[nod] = 0;
    qnod.push(nod);
    while( ! qnod.empty())
    {
        nod=qnod.front();
        qnod.pop();
        in[nod] = 0;
        for(int i=0;i<v[nod].size();i++)
        {
            if(drum[v[nod][i]] > drum[nod] + cost[nod][i] || viz[v[nod][i]] != verif)
            {
                drum[v[nod][i]] = drum[nod] + cost[nod][i];
                viz[v[nod][i]] = verif;
                if(in[v[nod][i]] != verif)
                    qnod.push(v[nod][i]);
                in[v[nod][i]] = verif;
            }
        }
    }
    last[verif-1] = drum[n] ;
    //fout<<verif-1<<" "<<drum[n]<<" * ";
    for(int i=0;i<=k;i++)
        cost2[verif-1][i] = drum[ck[i]];
}
int minim(int a,int b)
{
    if(a>b) return b;
    return a;
}
void init()
{
    for(int i=1;i<=(1<<(k+1));i++)
    {
        for(int j=0;j<=k;j++)
            d[i][j] = INF;
    }
    d[1][0] = 0;
}
int main()
{
    read();
    bford(1);
    if(k==0)
    {
        fout<<drum[n];
        return 0;
    }
    init();
    for(int i=1;i<=k;i++)
        bford(ck[i]);
    int pow = 1 << (k+1),aux,j,i;
    for(i=1;i<pow;i+=2)
    {
        for(j=0;j<=k;j++)
        {
            if(i & (1<<j))
            {
                for(int f=0;f<=k;f++)
                {
                    if(f==j) continue;
                    aux=f;
                    if(i & (1<<aux))
                        d[i][j] = minim(d[i][j] , d[i ^ (1<<j)][aux] + cost2[j][aux]);
                }
            }
        }
    }
    int r=INF;
    for(int i=0;i<=k;i++)
        r=minim(r,d[pow-1][i] + last[i]);
    fout<<r;
}