Cod sursa(job #812730)

Utilizator costyv87Vlad Costin costyv87 Data 14 noiembrie 2012 12:52:14
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.73 kb
#include <cstdio>
#include <vector>
#define INF 1000000000
using namespace std;
FILE *f,*g;
int dist[2010];
int bf[2010];
struct cp {int y,c;} ax2;
vector <cp> a[2010];
int d[20][20];
int H[2010]; //heap
int pos[2010]; //heap
int c[20];
int l,n,m,k;
int din[20][280000];

void up(int x)
{
     int ax;

     while (x/2 && dist[H[x/2]]>dist[H[x]])
     {
          ax=H[x],H[x]=H[x/2],H[x]=ax;
          pos[H[x]]=x, pos[H[x/2]]=x/2;
     }
}

void down(int x)
{
     int y=0,ax;
     while (y!=x)
     {
          y=x;
          if (y*2<=l && dist[H[x]]>dist[H[y*2]]) x=y*2;
          if (y*2+1<=l && dist[H[x]]>dist[H[y*2+1]]) x=y*2+1;
          ax=H[x], H[x]=H[y], H[y]=ax;
          pos[H[x]]=x, pos[H[y]]=y;
     }
}

void cut()
{
     H[1]=H[l];
     pos[H[l]]=1;
     l--;
     down(1);
}

void dijkstra(int x)
{
     int i,j,sz=1;

     for (i=1;i<=n;i++)
     {
          dist[i]=INF;
          pos[i]=i;
          H[i]=i;
     }

     l=n;
     dist[x]=0;
     pos[1]=x;  H[1]=x;
     pos[x]=1;  H[x]=1;

     while (l)
     {
          i=H[1];
          for (j=0;j<a[i].size();j++)
               if (dist[i]+a[i][j].c<dist[a[i][j].y])
               {
                    dist[a[i][j].y]=dist[i]+a[i][j].c;
                    up(pos[a[i][j].y]);
               }
          cut();
     }

     for (i=1;i<=k+2;i++)
          d[bf[x]][bf[c[i]]]=dist[c[i]];
}

void read()
{
     int i,y,x;
     fscanf(f,"%d%d",&n,&m);
     fscanf(f,"%d",&k);

     for (i=1;i<=n;i++)
          bf[i]=-1;

     bf[1]=1;
     c[1]=1;
     for (i=2;i<=k+1;i++)
     {
          fscanf(f,"%d",&c[i]);
          bf[c[i]]=i;
     }
     c[k+2]=n;
     bf[n]=k+2;

     for (i=1;i<=m;i++)
     {
          fscanf(f,"%d%d%d",&x,&y,&ax2.c);
          ax2.y=y;
          a[x].push_back(ax2);
          ax2.y=x;
          a[y].push_back(ax2);
     }
}


void solve()
{
     int i,j,lm,y;

     for (i=1;i<=k+2;i++)
          dijkstra(c[i]);

     /*for (i=1;i<=k+2;i++,fprintf(g,"\n"))
          for (j=1;j<=k+2;j++)
               fprintf(g,"%d ",d[i][j]);*/

     k+=2;
     lm=(1<<k)-1;

     for (i=0;i<=lm;i++)
          for (j=0;j<k;j++)
               din[j+1][i]=INF;
    din[1][1]=0;

     for (i=1;i<=lm;i++)
          for (j=0;j<k;j++)
               if ( i & (1<<j))
                    for (y=0;y<k;y++)
                         if (d[y+1][j+1]!=INF && (i & (1<<y)))
                              din[j+1][i]=min(din[j+1][i],din[y+1][i xor (1<<j)]+d[j+1][y+1]);
     fprintf(g,"%d",din[k][lm]);
}




int main()
{
     f=fopen("ubuntzei.in","r");
     g=fopen("ubuntzei.out","w");


     read();
     solve();

     fclose(g);
     return 0;
}