Cod sursa(job #2096712)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 29 decembrie 2017 17:14:43
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define nmax 505
#define pmax 55
#define inf 1000000000
using namespace std;
fstream f1("team.in", ios::in);
fstream f2("team.out", ios::out);
int n, p, dest[pmax], m, nrdest, dmin[nmax][nmax], viz[nmax], ctmin[pmax][pmax][pmax];
vector <pair <int, int>> v[nmax];
vector <int> d;
///dest[i]= nod destinatie pers i
///d- nodurile destinatie distincte
///nrdest= nr noduri dest distincte
///dmin[i][j]= distanta minima de la nodul destinatie i la nodul j
///ctmin[i][j][k]= ct minim pt a transporta acasa grupul {i, i+1, ...,j} pornind DIN nodul care e dest pt persoana k
void dijkstra(int x0)
{
    int vfmin, mini, j, i;

    for(j=1; j<=n; j++)
        {
            dmin[x0][j]=inf;
            viz[j]=0;
        }
    for(auto it= v[x0].begin(); it!=v[x0].end(); ++it)
        dmin[x0][(*it).first]=(*it).second;

    dmin[x0][x0]=0;
    viz[x0]=1;

    for(i=1; i<n; i++)
    {
       mini=inf;
       for(j=1; j<=n; j++)
        if((!viz[j])&&(mini> dmin[x0][j]))
           {
               mini=dmin[x0][j];
               vfmin=j;
           }
       viz[vfmin]=1;
       for(auto it=v[vfmin].begin(); it!=v[vfmin].end(); ++it)
           if(dmin[x0][(*it).first]> dmin[x0][vfmin]+ (*it).second)
              dmin[x0][(*it).first]= dmin[x0][vfmin]+ (*it).second;
    }
}
int main()
{
    int i, lung, j, k, x, y, c;
    f1>>p>>n>>m;
    for(i=1; i<=m; i++)
    {
        f1>>x>>y>>c;
        v[x].push_back({y, c});
        v[y].push_back({x, c});
    }
    d.push_back(1);
    for(i=1; i<=p; i++)
        {
            f1>>dest[i];
            d.push_back(dest[i]);
        }
    dest[0]=1;
    sort(d.begin(), d.end());
    nrdest=unique(d.begin(), d.end())- d.begin(); ///<=p+1

    for(i=0; i<nrdest; i++)
        dijkstra(d[i]);

    for(i=1; i<=p; i++)
        for(j=i; j<=p; j++)
           for(k=1; k<=p; k++)
                   ctmin[i][j][k]=inf;

    for(i=0; i<=p; i++)
        ctmin[i][i][i]=0;
    ///tot grupul {i, j} e transportat din nodul dest pt k in nodul dest pt un nod din grup (h din int {i,i+1, ...,j})
    ///iar din acest nod se imparte grupul

     for(lung=0; lung<p; lung++)
         for(i=1; i<=p-lung; i++)
      {
          j=i+lung;
          for(k=0; k<=p; k++)
          {
              if((i==j) && (j==k)) continue;
              ctmin[i][j][k]=inf;
              for(int h=i; h<=j; h++)
                  ctmin[i][j][k]=min(ctmin[i][j][k], ctmin[i][h-1][h]+ ctmin[h+1][j][h]+ dmin[dest[k]][dest[h]]);

          }
      }


    f2<<ctmin[1][p][0];
    return 0;
}