Cod sursa(job #1226382)

Utilizator RaduGabriel2012Dinu Radu RaduGabriel2012 Data 5 septembrie 2014 12:49:30
Problema Gather Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream f("gather.in");
ofstream g("gather.out");
 int k,n,m,a[20],dm[755],dmc[16][16][16],dp[(1<<15)][16],inf=2147000000,use[755],num[(1<<15)];

 struct vec
 { int nod,cost; };

  vec x,nw;

 struct cmp
 {
   bool operator() (vec a ,vec b)
   {
     return a.cost>b.cost;
   }
 };

 vector<int> v[755],l[755],c[755];

 priority_queue <vec,vector<vec>,cmp> heap;

 void Dij(int s,int cp)
 {  int i,p,pc;

   for(i=1;i<=n;i++)
     dm[i]=inf;

     dm[s]=0;

     x.nod=s; x.cost=0;

     heap.push(x);

     while(!heap.empty())
     {
         x=heap.top(); heap.pop();

      if (dm[x.nod]==x.cost)
        {
          p=x.nod; pc=x.cost;
         for(i=0;i<v[p].size();i++)
          {
             if (c[p][i]>=cp && x.cost+l[p][i]<dm[v[p][i]])
              { nw.nod=v[p][i];
                nw.cost=x.cost+l[p][i];
                dm[nw.nod]=nw.cost;
                heap.push(nw);
              }
          }
        }
      }
 }

int main()
{ int i,j,t,nr,x1,x2,len,cap,sol=inf;

   f>>k>>n>>m;
     a[1]=1; use[1]=1; k++;
    for(i=2;i<=k;i++)
     {f>>a[i]; use[a[i]]=i; }

   for(i=1;i<=m;i++)
   { f>>x1>>x2>>len>>cap;
       v[x1].push_back(x2);
       l[x1].push_back(len);
       c[x1].push_back(cap);
   }

   for(i=1;i<(1<<k);i++)
    num[i]=num[i&(i-1)]+1;

   for(i=1;i<=k;i++)
     for(j=1;j<=k;j++)
      for(t=1;t<=k;t++)
       dmc[i][j][t]=inf;

   for(i=1;i<=k;i++)
     for(j=0;j<=k;j++)
      { Dij(a[i],j);
         for(t=1;t<=n;t++)
          if (t!=a[i] && use[t])
           dmc[i][use[t]][j]=dm[t];
      }

      nr=(1<<k);


     for(j=0;j<nr;j++)
      for(i=1;i<=k;i++)
       dp[j][i]=inf;

       dp[1][1]=0;

    for(j=0;j<nr;j++)
     for(i=1;i<=k;i++)
      if (dp[j][i]!=inf)
       {
          for(t=1;t<=k;t++)
           if ( (!(j&(1<<(t-1)))) &&   dmc[i][t][num[j]]!=inf)
            { //if (j+(1<<(t-1))==3 && t==2) cout<<num[j]<<" "<<dmc[i][t][num[j]-1]<<"\n";
                dp[j+(1<<(t-1))][t]=min(dp[j+(1<<(t-1))][t],dp[j][i]+(num[j])*dmc[i][t][num[j]-1]);
            }
       }


       for(i=1;i<=k;i++)
        sol=min(sol,dp[nr-1][i]);

        g<<sol;
    return 0;
}