Cod sursa(job #2548079)

Utilizator Stefan_PiscuPiscu Stefan Constantin Stefan_Piscu Data 16 februarie 2020 10:48:19
Problema Gather Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <bits/stdc++.h>
using namespace std;

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

struct edge{
  long long dest, cost, d;
};

struct node{
  vector<edge> vec;
};

vector<node> g;

struct lols{
  long long poz, c;
};

bool operator<(lols a, lols b){
  return a.c>b.c;
}

void dijkstra(long long s, long long d, long long n, vector<long long> &sol){
  d--;
  priority_queue<lols> q;
  q.push({s, 1});
  while(!q.empty()){
    auto x=q.top();
    while(!q.empty()&&sol[q.top().poz]) q.pop(), x=q.top();
    if(!q.empty()){
      lols x=q.top();
      q.pop();
      long long nod=x.poz;
      long long cost=x.c;
      sol[nod]=cost;
      for(auto i:g[nod].vec){
        if(i.d>=d){
          q.push({i.dest, cost+i.cost});
        }
      }
    }
  }
  for(long long i=1;i<=n;++i) sol[i]--;
}

long long dp[17][1<<17];

long long dist[16][16][16];

int main(){
  long long n, m, k;
  fin>>k>>n>>m;
  g.resize(n+1);
  k++;
  vector<long long> v(k+1);
  v[1]=1;
  for(long long i=2;i<=k;++i){
    fin>>v[i];
  }
  for(long long i=1;i<=m;++i){
    long long a, b, c, d;
    fin>>a>>b>>c>>d;
    g[a].vec.push_back({b, c, d});
    g[b].vec.push_back({a, c, d});
  }
  for(long long i=1;i<=k;++i){
    for(long long j=1;j<=k;++j){
      vector<long long> sol(n+1);
      dijkstra(v[i], j, n, sol);
      for(long long p=1;p<=k;++p){
        dist[i][p][j]=sol[v[p]];
      }
    }
  }
  long long mask=1<<k;
  for(long long i=0;i<=k;++i){
    for(long long j=0;j<mask;++j){
      dp[i][j]=(1<<30);
    }
  }
  dp[1][1]=0;
  for(long long i=1;i<mask;i=(i+1)|1){
    for(long long poz=1;poz<=k;++poz){
      if(dp[poz][i]>=(1<<30)) continue;
      vector<long long> nobit;
      long long cnt=0;
      for(long long j=0;j<k;++j){
        if(i&(1<<j)) cnt++;
        else{
          nobit.push_back(j);
        }
      }
      for(auto j:nobit){
        if(dist[poz][j+1][cnt]>0){
          dp[j+1][i|(1<<j)]=min(dp[j+1][i|(1<<j)], dp[poz][i]+dist[poz][j+1][cnt]*cnt);
        }
      }
    }
  }
  long long sol=(1<<30);
  for(long long i=1;i<=k;++i){
    sol=min(sol, dp[i][mask-1]);
  }
  fout<<sol<<"\n";
  return 0;
}