Cod sursa(job #1840165)

Utilizator pepsiM4A1Ozturk Arif pepsiM4A1 Data 3 ianuarie 2017 20:36:31
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.9 kb
#include <cstdio>
#include <vector>
#define pb push_back
using namespace std;
const int nmax=2023,kmax=17,INF=1000000000;
bool vis[nmax];
int n,m,k;
int guys[kmax],arb[4*nmax],dist[kmax][nmax],dtmp[nmax];
vector<int>adj[nmax],cst[nmax];
int dyn[66000][17];
int source;
void update(int s,int e,int nod,int pos)
{
    if(s==e) arb[nod]=pos;
    else
    {
        int mij=(s+e)/2;
        if(pos<=mij) update(s,mij,2*nod,pos);
        else update(mij+1,e,2*nod+1,pos);
        if(dtmp[arb[2*nod]]<=dtmp[arb[2*nod+1]]) arb[nod]=arb[2*nod];
        else arb[nod]=arb[2*nod+1];
    }
}
void define_dist()
{
    for(int i=1;i<=n;i++)
    {
        vis[i]=0;
        dtmp[i]=INF;
        if(i==guys[source]) dtmp[i]=0;
        update(1,n,1,i);
    }
}
void dijkstra()
{
    for(int xyz=1;xyz<=n;xyz++)
    {
        int srs=arb[1];
        vis[srs]=1;
        dist[source][srs]=dtmp[srs];
        dtmp[srs]=INF;
        update(1,n,1,srs);
        int mar=adj[srs].size();
        for(int i=0;i<mar;i++)
        {
            if(vis[adj[srs][i]]==1) continue;
            if(dtmp[adj[srs][i]]>dist[source][srs]+cst[srs][i])
            {
                dtmp[adj[srs][i]]=dist[source][srs]+cst[srs][i];
                update(1,n,1,adj[srs][i]);
            }
        }
    }
}
int main()
{
    freopen ("ubuntzei.in","r",stdin);
    freopen ("ubuntzei.out","w",stdout);
    guys[0]=1;
    scanf("%d%d",&n,&m);
    scanf("%d",&k);
    for(int i=1;i<=k;i++) scanf("%d",&guys[i]);
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        adj[a].pb(b);
        adj[b].pb(a);
        cst[a].pb(c);
        cst[b].pb(c);
    }
    for(source=0;source<=k;source++)
    {
        define_dist();
        dijkstra();
    }
   /* for(int i=0;i<=k;i++)
    {
  //      for(int j=1;j<=n;j++) printf("%d ",dist[i][j]);
 //       printf("\n");
    }*/
    if(k==0)
    {
        printf("%d\n",dist[0][n]);
        return 0;
    }
    for(int i=0;i<(1<<(k+1));i++)
    {
        for(int j=0;j<=15;j++) dyn[i][j]=INF;
    }
    dyn[1][0]=0;
    for(int i=0;i<(1<<(k+1));i++)
    {
        for(int j=0;j<=k;j++)
        {
            if(dyn[i][j]==INF) continue;
            if(!(i&(1<<j))) continue;
          //  printf("I:%d J:%d | ",i,j);
            for(int s=0;s<=k;s++)
            {
                if(i&(1<<s)) continue;
        //        printf("(%d %d %d) ",(i^(1<<s)),s,dist[j][guys[s]]);
                dyn[i^(1<<s)][s]=min(dyn[i^(1<<s)][s],dyn[i][j]+dist[j][guys[s]]);
            }
      //      printf("\n");
        }
    }
    int minim=INF;
    /*for(int i=0;i<(1<<(k+1));i++)
    {
        for(int j=0;j<=k;j++) printf("%d ",dyn[i][j]);
        printf("\n");
    }*/
    for(int i=1;i<=k;i++)
    {
        if(minim>dyn[(1<<(k+1))-1][i]+dist[i][n]) minim=dyn[(1<<(k+1))-1][i]+dist[i][n];
    }
    printf("%d\n",minim);
}