Cod sursa(job #50407)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 7 aprilie 2007 17:24:55
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <stdio.h>
#include <vector>

using namespace std;

#define maxp 55
#define maxn 510
#define maxx 250010
#define maxv 1000000000
#define pb push_back

int n,m,P,l,sol;
int c[maxp][maxp][maxn];
int oras[maxp];
vector <int> a[maxn],ct[maxn];
int cost[maxn],p[maxn],g[maxn],h[maxn];
int drum[maxn][maxn];

void pop(int x)
{
    int aux;
    
    while ((x>1) && (cost[h[x]]<cost[h[x/2]]))
    {
          aux=h[x];
          h[x]=h[x/2];
          h[x/2]=aux;
          
          p[h[x]]=x;
          p[h[x/2]]=x/2;
          
          x=x/2;
    }
}

void push(int x)
{
     int y=0,aux;
     
     while (x!=y)   
     {
          y=x; 
          if ((y*2<=l) && (cost[h[x]]>cost[h[y*2]])) x=y*2;
          if ((y*2+1<=l) && (cost[h[x]]>cost[h[y*2+1]])) x=y*2+1;
          
          aux=h[x];
          h[x]=h[y];
          h[y]=aux;
          
          p[h[x]]=x;
          p[h[y]]=y;
     }
}

void Dijkstra(int nod)
{
     int i;
     l=n;
     
     for (i=1;i<=n;i++) 
     {
         cost[i]=maxv;
         h[i]=i;
         p[i]=i;
     }
     
     h[1]=nod;
     h[nod]=1;
     p[1]=nod;
     p[nod]=1;
     cost[nod]=0;
     
     while (l>0)
     {
           for (i=0;i<g[h[1]];i++)
             if (cost[h[1]]+ct[h[1]][i]<cost[a[h[1]][i]])
             {
                  cost[a[h[1]][i]]=cost[h[1]]+ct[h[1]][i];
                  
                  pop(p[a[h[1]][i]]);
             }
             
           p[h[1]]=0;
           h[1]=h[l];
           p[h[1]]=1;
           h[l]=0;
           l--;
           
           if (l>1) push(1);
     }
     
     for (i=1;i<=n;i++) drum[nod][i]=cost[i];     
}

int main()
{
    freopen("team.in","r",stdin);
    freopen("team.out","w",stdout);
    
    scanf("%d %d %d ",&P,&n,&m);
    
    int i,x,y,z,j,k;
    
    for (i=1;i<=m;i++) 
    {
        scanf("%d %d %d ",&x,&y,&z);
        a[x].pb(y);
        a[y].pb(x);
        ct[x].pb(z);
        ct[y].pb(z);
    }
    
    for (i=1;i<=n;i++) g[i]=a[i].size();
    
    for (i=1;i<=P;i++) scanf("%d ",&oras[i]);
    
    for (i=1;i<=P;i++) Dijkstra(oras[i]);
    Dijkstra(1);
        
    for (i=1;i<=P;i++)
      for (j=1;j<=P;j++)
        for (k=1;k<=n;k++) c[i][j][k]=maxv;
        
    for (i=1;i<=P;i++) c[i][i][oras[i]]=0;
    
    for (i=0;i<=P;i++)
      for (x=1;x+i<=P;x++)
      {
          y=x+i;
          for (k=x+1;k<y;k++)
            if (c[x][k-1][oras[k]]+c[k+1][y][oras[k]]<c[x][y][oras[k]]) c[x][y][oras[k]]=c[x][k-1][oras[k]]+c[k+1][y][oras[k]];
            
          if (c[x+1][y][oras[x]]<c[x][y][oras[x]]) c[x][y][oras[x]]=c[x+1][y][oras[x]];
          if (c[x][y-1][oras[y]]<c[x][y][oras[y]]) c[x][y][oras[y]]=c[x][y-1][oras[y]];
          
          for (j=1;j<=P;j++)
            for (k=1;k<=P;k++) 
              if (c[x][y][oras[j]]+drum[oras[j]][oras[k]]<c[x][y][oras[k]]) c[x][y][oras[k]]=c[x][y][oras[j]]+drum[oras[j]][oras[k]];
      }
      
    sol=maxv;
    
    for (i=1;i<=P;i++) 
      if (drum[1][oras[i]]+c[1][P][oras[i]]<sol) sol=drum[1][oras[i]]+c[1][P][oras[i]];      
      
    printf("%d\n",sol);
    
    return 0;
}