Cod sursa(job #2546121)

Utilizator isa_tudor_andreiAndrei Tudor isa_tudor_andrei Data 13 februarie 2020 20:25:34
Problema Ubuntzei Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.88 kb
#include <bits/stdc++.h>
#define NMAX 2000
#define KMAX 65536

using namespace std;

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

const long long INF = 20000000000000001;

struct Edge {
  int dest;
  long long cost;
  bool operator<(const Edge& other) const
  {
        return cost>other.cost;
  }
};

vector<Edge> G[NMAX + 1];
priority_queue<Edge> pq;
long long dp[KMAX + 1][20], dist[20][NMAX + 1];
int n, m, k, f[NMAX + 1];

void Dijkstra( int source ) {
  for( int i = 1; i <= NMAX; i ++ )
    dist[source][i] = INF;
  pq.push({f[source], 0});
  while( !pq.empty() ) {
    int node = pq.top().dest;
    long long cost = pq.top().cost;
    pq.pop();
    if( dist[source][node] == INF ) {
      dist[source][node] = cost;
      for( auto it : G[node] )
        if( dist[source][it.dest] == INF )
          pq.push({ it.dest, it.cost + cost });
    }
  }
}

long long calc( int mask, int last ) {
  if(  dp[mask][last] != INF )
    return dp[mask][last];
  if( mask == 0 )
    return 0;
  for( int i = 0; i <= k + 1; i ++ )
    if( mask & (1 << i) ) {
      if( i == 0 && mask == (1<<last) + 1 )
        continue;
      dp[mask][last] = min( dp[mask][last], calc(mask ^ (1 << i), i) + dist[last][f[i]] );
    }
 return dp[mask][last];
}

int main() {
    fin>>n>>m;
    fin>>k;
    for( int i = 1; i <= k; i ++ ) {
      int x;
      fin>>f[i];
    }
    f[0] = 1;
    f[k + 1] = n;
    for( int i = 1; i <= m; i ++ ) {
      int x, y;
      long long p;
      fin>>x>>y>>p;
      G[x].push_back({y,p});
      G[y].push_back({x,p});
    }
    for( int i = 1; i <= k; i ++ )
      Dijkstra( i );
    Dijkstra(0);
    Dijkstra(k + 1);
    for( int i = 0; i <= 1<<(k + 1); i ++ )
      for( int j = 0; j <= k + 1; j ++ )
        dp[i][j] = INF;
    calc( (1<<(k+1)) - 1, k + 1);
    fout<<dp[(1<<(k+1)) - 1][k + 1];
    return 0;
}