Cod sursa(job #2937094)

Utilizator iraresmihaiiordache rares mihai iraresmihai Data 9 noiembrie 2022 21:36:53
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.68 kb
#include <iostream>
#include <vector>
#include <queue>

#define MAXK 15
#define MAXN 2000
#define MAXDIST 200000000
#define MAXMASK 131072
using namespace std;

///citirea lui Cristian Francu
#define MAXLOG10 10
#define BUFSIZE (128 * 1024)

FILE *fin, *fout;
int p10[MAXLOG10 + 1] = { 0, 1, 10, 100, 1000, 10000, 100000, 1000000,
  10000000, 100000000, 1000000000 }; // santinela pe prima pozitie
int rpos; char rbuf[BUFSIZE];
int wpos; char wbuf[BUFSIZE];

// initializare citire
static inline void initRead() {
  rpos = BUFSIZE - 1;
}

// citire caracter
static inline char readChar() {
  if ( !(rpos = (rpos + 1) & (BUFSIZE - 1)) )
    fread( rbuf, 1, BUFSIZE, fin );
  return rbuf[rpos];
}

// citire intreg cu semn
int readInt() { // citeste un intreg
  int ch, res = 0, semn = 1;

  while ( isspace( ch = readChar() ) );
  if ( ch == '-' ) {
    semn = -1;
    ch = readChar();
  }
  do
    res = 10 * res + ch - '0';
  while ( isdigit( ch = readChar() ) );

  return semn * res;
}

struct edge{
  int b, cost;
};

struct node{
  int dist;
  bool visited;
  vector <edge> neighbours;
};
///am schimbat semnul la operator :))
bool operator<(edge a, edge b) {
  return a.cost > b.cost;
}

priority_queue <edge> pq;
node graph[MAXN];
node graphWithGoodPos[MAXK];
int valuablePos[MAXK + 2];
long long dp[MAXK + 2][MAXMASK];

void addEdge(int a, int b, int cost) {
  graph[a].neighbours.push_back({b, cost});
  graph[b].neighbours.push_back({a, cost});
}

void addEdgeInGraphWithGoodPos(int a, int b, int cost) {
  graphWithGoodPos[a].neighbours.push_back({b, cost});
  graphWithGoodPos[b].neighbours.push_back({a, cost});
}

void dijkstra(int startPos, int n) {
  int i;
  edge pos;

  for ( i = 0; i < n; i++ ) {
    graph[i].dist = MAXDIST;
  }

  graph[startPos].dist = 0;
  for ( edge i2 : graph[startPos].neighbours ) {
    pq.push(i2);
    graph[i2.b].dist = i2.cost;
  }

  while ( !pq.empty() ) {
    pos = pq.top();
    pq.pop();

    if ( graph[pos.b].dist == pos.cost ) {
      graph[pos.b].dist = pos.cost;
      for ( edge i2 : graph[pos.b].neighbours ) {
        if ( pos.cost + i2.cost < graph[i2.b].dist ) {
          graph[i2.b].dist = pos.cost + i2.cost;
          pq.push({i2.b, pos.cost + i2.cost});
        }
      }
    }
  }
}

int main() {
  fin = fopen("ubuntzei.in", "r");
  fout = fopen("ubuntzei.out", "w");

  int n, m, k, i, a, b, cost, i2;

  initRead();

  n = readInt();
  m = readInt();
  k = readInt();

  valuablePos[0] = 0;
  for ( i = 1; i <= k; i++ ) {
    valuablePos[i] = readInt();
    valuablePos[i]--;
  }
  valuablePos[k + 1] = n - 1;
  k += 2;

  for ( i = 0; i < m; i++ ) {
    a = readInt();
    b = readInt();
    cost = readInt();
    a--;
    b--;

    addEdge(a, b, cost);
  }

  for ( i = 0; i < k; i++ ) {
    dijkstra(valuablePos[i], n);

    for ( i2 = i + 1; i2 < k; i2++ ) {
      //printf("%d %d %d\n", valuablePos[i] + 1, valuablePos[i2] + 1, graph[valuablePos[i2]].dist);
      addEdgeInGraphWithGoodPos(i, i2, graph[valuablePos[i2]].dist);
    }
  }

  for ( i = 0; i < (1 << k); i++ ) {
    for ( i2 = 0; i2 < k; i2++ ) {
      dp[i2][i] = (long long) MAXDIST * (MAXK + 2) + 1;
    }
  }

  dp[0][1] = 0;

  for ( i = 1; i < (1 << k); i++ ) {
    for ( i2 = 0; i2 < k; i2++ ) {
      if ( i & (1 << i2) ) {
        for ( edge i3 : graphWithGoodPos[i2].neighbours ) {
          if ( i & (1 << i3.b) ) {
            dp[i3.b][i] = min(dp[i3.b][i], (long long) dp[i2][i - (1 << i3.b)] + i3.cost);
          }
        }
      }
    }
  }

  fprintf(fout, "%lld\n", dp[k - 1][(1 << k) - 1]);

  fclose(fin);
  fclose(fout);

  return 0;
}