Cod sursa(job #2136389)

Utilizator smashsmash everything smash Data 19 februarie 2018 21:29:55
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <fstream>
#include<vector>
using namespace std;
ifstream cin ("ubuntzei.in");
ofstream cout ("ubuntzei.out");
int n,m,k,date[22],heap[2002],poz[2002],best[16][2002],l,data[1<<16][16],q;
vector <int> g[2002],cost[2002];
void read ()
{ int x,y,z;
    cin>>n>>m>>k;
    for(int i=0;i<k;i++) cin>>date[i]; date[k]=1;
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y>>z;
        g[x].push_back(y);
        g[y].push_back(x);
        cost[x].push_back(z);
        cost[y].push_back(z);
    }
    for(q=0;q<=k;q++)
    for(int i=1;i<=n;i++) best[q][i]=1000000000;
}
void down (int pz)
{
    int fiu=0;
    if(pz*2<=l) fiu=pz*2;
    if(pz*2+1<=l && best[q][heap[fiu]]>best[q][heap[fiu+1]]) fiu++;
    while(fiu && best[q][heap[fiu]]<best[q][heap[pz]])
    {
        swap(heap[fiu],heap[pz]); swap(poz[heap[fiu]],poz[heap[pz]]);
        pz=fiu;
        fiu=0;
        if(pz*2<=l) fiu=pz*2;
        if(pz*2+1<=l && best[q][heap[fiu]]>best[q][heap[fiu+1]]) fiu++;
    }
}
void climb (int pz)
{
    while(pz>1 && best[q][heap[pz]]<best[q][heap[pz/2]])
    {
        swap(heap[pz/2],heap[pz]); swap(poz[heap[pz/2]],poz[heap[pz]]); pz/=2;
    }
}
void dijkstra ()
{
    heap[1]=date[q]; poz[date[q]]=1; l=1; best[q][date[q]]=0; for(int i=1;i<=n;i++) poz[i]=0;
    while(l)
    {
        int nod=heap[1];
        heap[1]=heap[l--]; poz[heap[1]]=1;
        down(1);
        for(int i=0;i<g[nod].size();i++)
        {
            int fiu=g[nod][i],c=cost[nod][i];
            if(best[q][nod]+c<best[q][fiu])
            {
                best[q][fiu]=best[q][nod]+c;
                if(poz[fiu]==0) poz[fiu]=++l,heap[l]=fiu;
                climb(poz[fiu]);
            }
        }
    }

}
void solve ()
{ int lim=1<<k; lim--;
    for(int i=0;i<=lim;i++)
        for(int j=0;j<k;j++) data[i][j]=1000000000;
     for(int i=0;i<k;i++)
        data[1<<i][i]=best[k][date[i]];
     for(int i=0;i<=lim;i++)
     {
         for(int j=0;j<k;j++)
        if(data[i][j]!=1000000000)
        {
            for(int u=0;u<k;u++)
            { int y=1<<u;
                if( (i | y )!= i)
                {
                    data[i | y][u]=min(data[ i | y ][u],data[i][j]+best[j][date[u]]);
                }
            }
        }
     } int maxim=1000000000;
     for(int i=0;i<k;i++)
     {
         maxim=min(maxim,data[lim][i]+best[i][n]);
     }
     if(k==0) maxim=best[k][n];
     cout<<maxim;
}
int main()
{
    read();
    for(q=0;q<=k;q++)
    dijkstra();
    solve();
    cin.close();
    cout.close();
    return 0;
}