Cod sursa(job #1646892)

Utilizator LipanmateiLipan Radu-Matei Lipanmatei Data 10 martie 2016 18:08:13
Problema Ubuntzei Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>

#define Nmax 2001
#define INF ((1<<16)-1)
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int n,m,k;
vector < pair <int,int> > v[Nmax];
vector < int > ubu;
vector < int > dist[20];
vector < int > D[18];

void read()
{
    fin>>n>>m;
    fin>>k;
    ubu.push_back(1);
    for(int i=1;i<=k;i++)
    {
        int c;
        fin>>c;
        ubu.push_back(c);
    }
    ubu.push_back(n);
    for(int i=1;i<=m;i++)
    {
        int x,y,cost;
        fin>>x>>y>>cost;
        v[y].push_back(make_pair(x,cost));
        v[x].push_back(make_pair(y,cost));
    }
}

void B_F(int i_start)
{
    int start=ubu[i_start];
    queue < int > Q;
    vector < bool > inQ;

    inQ.assign(n+2,0);
    dist[i_start].assign(n+2,INF);
    dist[i_start][start]=0;
    Q.push(start);

    while(!Q.empty())
    {
        int nod = Q.front();
        Q.pop();
        inQ[nod]=0;
        int d = dist[i_start][nod];
        vector < pair < int,int > >:: iterator ivector=v[nod].begin();
        for(;ivector!=v[nod].end();ivector++)
            if(d+ivector->second< dist[i_start][ivector->first])
            {
                dist[i_start][ivector->first]=d+ivector->second;
                if(!inQ[ivector->first])
                    Q.push(ivector->first),inQ[ivector->first]=1;
            }
    }
}

void initdrum()
{
    for(int i=0; i<=k+2 ; i++)
        D[i].assign(1<<(k+3), INF);
}

int construire_drum(int i_nod_final,int cod)
{
    if(cod==0)
        return dist[0][ubu[i_nod_final]];
    if(D[i_nod_final][cod]<INF)
        return D[i_nod_final][cod];
    for(int i=1;i<=k;i++)
    {
        int val = INF;
        if(cod>>(i-1)&1)
        {
            val=construire_drum(i,cod-(1<<(i-1)));
            val+=dist[i][ubu[i_nod_final]];
        }
        if(val < D[i_nod_final][cod])
            D[i_nod_final][cod] = val;
    }
    return D[i_nod_final][cod];
}
int main()
{
    read();
    for(int i=0;i<ubu.size()-1;i++)
        B_F(i);
    initdrum();
    fout<<construire_drum(k+1,(1<<k)-1);
    return 0;
}