Cod sursa(job #2220395)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 11 iulie 2018 16:47:31
Problema Ubuntzei Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.88 kb
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

ifstream fin ("ubuntzei.in");
ofstream fout ("ubuntzei.out");

int N,M;
int K;
int target[2001]; /// asociem fiecarui oras obligatoriu un numar

vector < vector <int> > Ad(2001);
vector < vector <int> > Cost(2001);

struct Stare
{
  int nod;
  int dist;
  int nr_t; /// nr de orase vizitate din cele obligatorii
  int v[16];
};

struct comp
{
  bool operator() ( const Stare & A, const Stare & B )
  {
    return ( A.dist > B.dist ) || ( A.dist == B.dist && A.nr_t < B.nr_t);
  }
};

priority_queue < Stare, vector < Stare >, comp > Heap;

void Read()
{
  fin >> N >> M;

  int tmp, index = 0;

  fin >> K;
  for( int i = 1; i <= K; ++i )
  {
    fin >> tmp;

    target[tmp] = ++index;
  }

  int a,b,d;

  for( int i = 1; i <= M; ++i )
   {
     fin >> a >> b >> d;

     Ad[a].push_back(b);
     Cost[a].push_back(d);

     Ad[b].push_back(a);
     Cost[b].push_back(d);
   }

  fin.close();
}

void Do()
{
  Stare tmp;

  tmp.nod = 1;
  tmp.dist = 0;
  tmp.nr_t = 0;
  for( int i = 0; i <= K; ++i ) tmp.v[i] = 0;


  /*tmp.nod = 3;
  tmp.dist = 2;
  tmp.nr_t = 1;
  tmp.v[1] = 1;*/

  Heap.push( tmp );

  int d_curent;
  int n_curent;
  int nr_t_curent;
  int v_curent[16];
  int w;

  while( ! Heap.empty() )
  {
     /*fout << Heap.top().nod << " dist: " << Heap.top().dist << '\n' << "viz : ";
     for( int i = 1; i <= K; ++i )
       fout << Heap.top().v[i] << ' ';
     fout << '\n';
     fout << '\n';*/

     n_curent = Heap.top().nod;
     d_curent = Heap.top().dist;
     nr_t_curent = Heap.top().nr_t;
     for( int i = 1; i <= K; ++i )
       v_curent[i] = Heap.top().v[i];

     Heap.pop();

     if( n_curent == N && nr_t_curent == K )
     {
       fout << d_curent << '\n';

       //for( int i = 1; i <= K; ++i )
       //  fout << v_curent[i] << ' ';

        return;
     }

     for( int i = 0; i < Ad[n_curent].size(); ++i )
     {
       w = Ad[n_curent][i];

       tmp.nod = w;
       tmp.dist = d_curent + Cost[n_curent][i];

       if( target[ w ] > 0 )
       {
         ++v_curent[ target[w] ];
         if( v_curent[ target[w] ] == 1 ) ++nr_t_curent;
       }

       tmp.nr_t = nr_t_curent;

       for( int i = 1; i <= K; ++i )
        tmp.v[i] = v_curent[i];

        Heap.push( tmp );

       if( target[ w ] > 0 )
       {
         --v_curent[ target[w] ];
         if( v_curent[ target[w] ] == 0 ) ++nr_t_curent;
       }
     }
  }
}

void Test()
{
  for( int i = 1; i <= N; ++i )
   {  for( int j = 0; j < Ad[i].size(); ++j )
        fout << Ad[i][j] << ' ';

      fout << '\n';

      for( int j = 0; j < Ad[i].size(); ++j )
        fout << Cost[i][j] << ' ';

      fout << '\n';
      fout << '\n';
   }

}

int main()
{
    Read();
    Do();

    return 0;
}