Cod sursa(job #2362323)

Utilizator andaraluca2001Anda Epure andaraluca2001 Data 3 martie 2019 10:16:33
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <bits/stdc++.h>
using namespace std;
const int MAX=100005;
const int INF=1e9;
int n,m,x,y,c,st,dr,cost,d[2005],k,val,id[2005],noduri[2005],cur;
int roads[17][17];
int dp[1<<17][20],bits[20];
bool fr[17];
bool sel[2001];
vector<pair<int,int> >graf[2005];
priority_queue<pair<int,int> >h;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");

void dijkstra(int start)
{
    for(int i=1;i<=n;i++)
    {
        d[i]=INF;
        sel[i]=false;
    }
    d[start]=0;
    h.push(make_pair(-d[start],start));

    while(!h.empty())
    {
        while(!h.empty() && sel[h.top().second]) h.pop();
       if(h.empty())
       {

           return;
       }
       x=h.top().second;
       h.pop();
       sel[x]=true;

       for(int i=0;i<graf[x].size();i++)
       {
           pair<int,int> p=graf[x][i];
           y=p.second;
           c=p.first;

           if(d[x]+c<d[y])
           {
               d[y]=d[x]+c;
               h.push(make_pair(-d[y],y));
           }
       }
    }


}
int main()
{
    in>>n>>m>>k;

    for(int i=1;i<=k;i++)
    {
        in>>val;
        fr[val]=1;
    }

    fr[1]=fr[n]=1;
    cur=1;
    for(int i=1;i<=n;i++)
    {
        if(fr[i]==1)
        {
            id[i]=cur;
            noduri[cur]=i;
            cur++;
        }
    }


    for(int i=1;i<=m;i++)
    {
        in>>st>>dr>>cost;
        graf[st].push_back(make_pair(cost,dr));
        graf[dr].push_back(make_pair(cost,st));
    }

   //for(int i=1;i<=n;i++) out<<fr[i]<<" ";

    for(int i=1;i<=n;i++)
    {
        if(fr[i]==1)
        {

            dijkstra(i);
      for(int j=1;j<=n;j++)
    {
        if(fr[j]==1)
        {
            roads[id[i]][id[j]]=d[j];
        }
    }

        }


    }

/*for(int i=1;i<=k+2;i++)
{
    for(int j=1;j<=k+2;j++) out<<roads[i][j]<<" ";
    out<<'\n';
}*/

     cur--;
     for(int i=1;i<=k+2;i++)
       for(int j=1;j<=k+2;j++) if(roads[i][j]==0) roads[i][j]=INF;


	  int val=(1<<cur);
	  //out<<val<<'\n';
    for(int i=0;i<(1<<16);i++)
       for(int j=0;j<16;j++) dp[i][j]=INF;


   dp[1][0]=0;

  /* for(int i=3;i<val;i+=2)
   {
       for(int j=0;j<k;j++)
       {
           if(i&(1<<j))
           {
               int ii=i^(1<<j);

               for(int jj=0;j<k;j++)
               {
                   if(ii&(1<<jj)) dp[i][j]=min(dp[i][j],dp[ii][jj]+roads[jj+1][j+1]);
               }
           }
       }
   }*/

           for(int mask=0;mask<val;mask++)

        {
                y=0;
                for(int k=0;(1<<k)<=mask;k++)
                {
                            if(mask&(1<<k))
                        {
                            bits[++y]=k;
                        }

                }

                for(int fr=1;fr<=y;fr++)
                {
                        int bt=bits[fr];
                        /// dp[mask][bt]
                        for(int lo=1;lo<=y;lo++)
                        {
                                if(lo==fr) continue;
                                int fk=bits[lo];
                                dp[mask][bt]=min(dp[mask][bt],dp[mask-(1<<bt)][fk]+roads[fk+1][bt+1]);

                        }
                }
        }
  int res=dp[val-1][cur-1];
  out<<res;

    return 0;
}