Cod sursa(job #2942200)

Utilizator Remus.RughinisRemus Rughinis Remus.Rughinis Data 19 noiembrie 2022 13:00:50
Problema Ubuntzei Scor 65
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.73 kb
#include <iostream>
#include <fstream>
#include <vector>
#define MAXN 2000
#define MAXK 16
#define MAXVAL 200000000

using namespace std;

int lt[MAXN][MAXN], city[MAXN];
int d[MAXN][1 << MAXK], ck[MAXK];

int* getMatrix(int a, int b){
  int aux;
  if(a > b){
    aux = a;
    a = b;
    b = aux;
  }

  return &lt[a][b];
}

void fancyPrint(int n){
  int i, j;

  for(i = 0; i < n; i ++){
    for(j = 0; j <= i; j ++)
      printf("  ");

    for(j = i + 1; j < n; j ++){
      printf("%d ", lt[i][j]);
    }
    printf("\n");
  }
}

int main(){
  int n, m, i, a, b, c, j, k, mask, h;

  ifstream fin ("ubuntzei.in");
  fin >> n >> m;

  fin >> k;
  for(i = 0; i < k; i ++){
    fin >> a;
    a --;

    city[a] = 1;
    ck[i] = a;
  }
  city[0] = 1;
  city[n - 1] = 1;
  ck[k] = n-1;
  k ++;

  for(i = 0; i < m; i ++){
    fin >> a >> b >> c;
    a --;
    b --;
    
    *getMatrix(a,b) = c;
  }
  fin.close();

  // fancyPrint(n);

  for(i = 0; i < n ; i ++){
    if(!city[i]){

      for(j = 0; j < n; j ++){
        if(*getMatrix(i, j) != 0){

          for(h = j + 1; h < n; h ++){
            if(*getMatrix(i, h) != 0 && (*getMatrix(i, j) + *getMatrix(i, h) < *getMatrix(j, h) || *getMatrix(j, h) == 0))
              *getMatrix(j, h) = *getMatrix(i, j) + *getMatrix(i, h);
          }

        }
        *getMatrix(i, j) = 0;
      }
    }
  }

  // for(i = 0; i < k; i ++){
  //   printf("%d ", ck[i]);
  // }
  // printf("\n");

  for(mask = 0; mask < (1 << MAXK); mask ++){
    for(i = 0; i < k; i ++){
      int nodei = ck[i];
      d[nodei][mask] = MAXVAL;
    }
  }
  d[0][0] = 0;
  for(j = 0; j < k; j ++){
    int nodej = ck[j];
    if(*getMatrix(0, nodej) != 0)
      d[nodej][1 << j] = *getMatrix(0, nodej);
  }

  for(mask = 0; mask < (1 << MAXK); mask ++){
    for(i = 0; i < k; i ++){
      int nodei = ck[i];

      if(mask & (1 << i)){ // Daca exista nodul nodei in masca
        for(j = 0; j < k; j ++){
          int nodej = ck[j];
          if(*getMatrix(nodei, nodej) > 0){ // Daca exista muchie de la nodei la nodej
            int val = d[nodei][mask] + *getMatrix(nodei, nodej);

            // Daca e cel mai rapid traseu de pana acum sa mergem prin nodei la nodej
            if(!(mask & (1 << j)) && val < d[nodej][mask | (1 << j)]){
              d[nodej][mask | (1 << j)] = val;
            }
          }
        }
      }
    }
  }

  // printf("\n");
  // for(mask = 0; mask < 16; mask ++){
  //   for(i = 0; i < k; i ++){
  //     int nodei = ck[i];
  // 
  //     if(d[nodei][(mask)] > 0){
  //       printf("d[%d][%d] = %d  ", nodei, mask, d[nodei][mask]);
  //     }
  //   }
  //   printf("\n");
  // }

  // cout << endl;
  // fancyPrint(n);

  ofstream fout ("ubuntzei.out");
  fout << d[n-1][(1 << k) - 1] << endl;
  fout.close();

  return 0;
}