Cod sursa(job #1592371)

Utilizator raduiris94Alexa Radu raduiris94 Data 7 februarie 2016 15:48:34
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
# include <fstream>
# include <iostream>
# include <vector>
# include <set>
# define INF 2000000000
# define DIM 2048
# define MAXK 20
# define pb push_back
# define mp make_pair
# define fs first
# define sc second
# define min(a,b) (a<b?a:b)
using namespace std;
int n, m, K, dd[MAXK][MAXK], vk[MAXK], w[DIM], v[DIM], d[DIM], bst[20*DIM][MAXK], sol=INF;
vector< pair<int,int> >G[DIM];
set< pair<int,int> >S;
 
void read ()
{
    ifstream fin ("ubuntzei.in");
    fin>>n>>m>>K;
    for(int i=1;i<=K;++i)
    {
        fin>>vk[i];
        w[vk[i]]=i;
    }
    w[n]=K+1;
    int x, y, z;
    for(int i=1;i<=m;++i)
    {
        fin>>x>>y>>z;
        G[x].pb(mp(y, z));
        G[y].pb(mp(x, z));
    }
}
 
void f (int poz)
{
    for(int i=1;i<=n;++i)
        d[i]=INF, v[i]=0;
    S.insert(mp(0,vk[poz]));
    d[vk[poz]]=0;
    int k, dst;
    while (S.size())
    {
        k=(*S.begin()).sc;dst=(*S.begin()).fs;
        S.erase(S.begin());
        if (!v[k])
        {
            v[k]=1;
            if (w[k])dd[poz][w[k]]=dst;
            for(vector< pair<int,int> >::iterator I=G[k].begin();I!=G[k].end();++I)
                if (!v[I->fs] && d[k]+I->sc<d[I->fs])
                {
                    d[I->fs]=d[k]+I->sc;
                    S.insert(mp(d[I->fs], I->fs));
                }
        }
    }
}
     
void distante ()
{
    vk[0]=1;
    for(int i=0;i<=K;++i)
        f(i);
}
 
void dinamo ()
{
    for(int i=1;i<=K;++i)
        bst[1<<(i-1)][i-1]=dd[0][i];
    for(int i=1;i<(1<<K);++i)
        for(int j=0;j<K;++j)
            if (i&(1<<j))
                for(int k=0;k<K;++k)
                    if (!(i&(1<<k)))
                    {
                        if (bst[i|(1<<k)][k]==0)bst[i|(1<<k)][k]=bst[i][j]+dd[j+1][k+1];
                        else bst[i|(1<<k)][k]=min(bst[i|(1<<k)][k],bst[i][j]+dd[j+1][k+1]);
                    }
    int i=(1<<K)-1;
    for(int j=0;j<K;++j)
        sol=min(sol,bst[i][j]+dd[j+1][K+1]);
}
 
int main()
{
    read ();
    distante ();
    ofstream fout ("ubuntzei.out");
    if (K==0)
        fout<<dd[0][1];
    else if (K==1)
        fout<<dd[0][1]+dd[1][2];
    else
    {
        dinamo ();
        fout<<sol;
    }
    return 0;
}