Cod sursa(job #35812)

Utilizator stef2nStefan Istrate stef2n Data 22 martie 2007 16:07:32
Problema Team Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.54 kb
/*
        Complexitate: O(P*N^2 + P^4)
*/

#include <stdio.h>

#define infile "team.in"
#define outfile "team.out"
#define NMAX 502
#define PMAX 52
#define INF 100000000

FILE *fin,*fout;
int p,n,cost[NMAX][NMAX];
int dest[PMAX];
bool isdest[NMAX];
int C[NMAX][NMAX];
bool vizitat[NMAX];
int SOL[PMAX][PMAX][PMAX];

void citire()
  {
   int i,j,m;
   int u,v,c;
   fin=fopen(infile,"r");
   fscanf(fin,"%d\n%d\n%d",&p,&n,&m);
   for(i=0;i<n;i++)
      for(j=0;j<n;j++)
         if(i==j)
           cost[i][j]=0;
         else
           cost[i][j]=INF;
   for(i=0;i<m;i++)
      {
       fscanf(fin,"%d %d %d",&u,&v,&c);
       u--;v--;
       cost[u][v]=cost[v][u]=c;
      }
   for(i=0;i<p;i++)
      {
       fscanf(fin,"%d",&dest[i]);
       dest[i]--;
      }
   fclose(fin);
  }

void dijkstra(int varf, int *C)
  {
   int i,j;
   for(i=0;i<n;i++)
      {
       vizitat[i]=0;
       C[i]=cost[varf][i];
      }
   vizitat[varf]=1;
   for(j=0;j<n-1;j++)
      {
       int min=INF,poz=-1;
       for(i=0;i<n;i++)
          if(!vizitat[i] && min>C[i])
            {
             min=C[i];
             poz=i;
            }
       if(poz==-1)
         return;
       vizitat[poz]=1;
       for(i=0;i<n;i++)
          if(!vizitat[i] && C[i]>min+cost[poz][i])
            C[i]=min+cost[poz][i];
      }
  }

void init()
  {
   int i,j,k;
   for(i=0;i<n;i++)
      isdest[i]=0;
   for(i=0;i<p;i++)
      isdest[dest[i]]=1;

   if(!isdest[0])
     dijkstra(0,C[0]);
   for(i=0;i<n;i++)
      if(isdest[i])
        dijkstra(i,C[i]);

   for(i=0;i<p;i++)
      for(j=0;j<p;j++)
         for(k=0;k<p;k++)
            SOL[i][j][k]=-1;
  }

void solve(int li, int ls, int varf)
  {
   int i;
   if(li==ls)
     {
      SOL[li][ls][varf]=0;
      return;
     }
   if(varf==li)
     SOL[li][ls][varf]=0;
   else
     SOL[li][ls][varf]=INF;
   for(i=li;i<varf;i++)
      {
       solve(li,varf-1,i);
       if(SOL[li][ls][varf] > SOL[li][varf-1][i] + C[dest[varf]][dest[i]])
         SOL[li][ls][varf] = SOL[li][varf-1][i] + C[dest[varf]][dest[i]];
      }
   int aux;
   if(varf==ls)
     aux=0;
   else
     aux=INF;
   for(i=varf+1;i<=ls;i++)
      {
       solve(varf+1,ls,i);
       if(aux > SOL[varf+1][ls][i] + C[dest[varf]][dest[i]])
         aux = SOL[varf+1][ls][i] + C[dest[varf]][dest[i]];
      }
   SOL[li][ls][varf]+=aux;
  }


int main()
{
int min=INF;
citire();
init();
for(int i=0;i<p;i++)
   {
    solve(0,p-1,i);
    if(min > C[0][dest[i]] + SOL[0][p-1][i])
      min = C[0][dest[i]] + SOL[0][p-1][i];
   }
fout=fopen(outfile,"w");
fprintf(fout,"%d\n",min);
fclose(fout);
return 0;
}