Cod sursa(job #2457327)

Utilizator Lazar_LaurentiuLazar Laurentiu Lazar_Laurentiu Data 17 septembrie 2019 12:32:39
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

#define VMAX 1000000000
#define CMAX 66550
#define MAX 2010
#define KMAX 20

#define x first
#define y second

using namespace std;

int n,m,k,a,b,c,ansf;
int p[KMAX];
int d[MAX][MAX];
int ans[CMAX][KMAX];
bool ex[KMAX];
vector< pair<int,int> > nd[MAX];
priority_queue< pair<int,int> > q;
pair<int,int> ac;

void init(){
  for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
      d[i][j]=VMAX;
  for(int i=0;i<CMAX;i++) for(int j=0;j<KMAX;j++)
    ans[i][j]=VMAX;
  ans[1][0]=0;
}

void calc_dis(int pp,int vd[MAX]){
  vd[pp]=0;
  q.push(make_pair(0,pp));
  while(!q.empty()){
    ac=q.top(); q.pop();
    if(-ac.x>vd[ac.y])continue;
    for(auto i:nd[ac.y]){
      int da=vd[ac.y]+i.y;
      if(da<vd[i.x]){
        vd[i.x]=da;
        q.push(make_pair(-da,i.x));
      }
    }
  }
}

void update(int &ansa,int ca,int bd){
  for(int b=1,nrb=0;b<=ca;b<<=1,nrb++)
    if((ca|b)==ca)
      ansa=min(ansa,ans[ca][nrb]+d[p[nrb]][p[bd]]);
}

int main()
{
    ifstream f ("ubuntzei.in");
    ofstream g ("ubuntzei.out");
    f>>n>>m>>k;
    for(int i=1;i<=k;i++)f>>p[i];
    p[0]=1;
    for(int i=1;i<=m;i++)
      f>>a>>b>>c,
      nd[a].push_back(make_pair(b,c)),
      nd[b].push_back(make_pair(a,c));
    init();
    for(int i=1;i<=n;i++) calc_dis(i,d[i]);

//    for(int i=1;i<=n;i++)
//      for(int j=1;j<=n;j++)
//        cout<<i<<" -> "<<j<<": "<<d[i][j]<<'\n';
    for(int cb=2;cb<(1<<(k+1));cb++){

      for(int i=0;i<KMAX;i++)ex[i]=0;

      for(int b=1,nrb=0;b<=cb;b<<=1,nrb++)
        if((cb|b)==cb)ex[nrb]=1;

//      for(int i=0;i<KMAX;i++)cout<<ex[i]; cout<<'\n';

      for(int i=1;i<=k;i++)
        if(ex[i]){
//          cout<<k<<'\n';
          update(ans[cb][i],cb-(1<<i),i);
//          cout<<ans[cb][i]<<'\n';
        }

//        cout<<"\n\n";

    }
    ansf=VMAX;
//    cout<<">"<<ans[3][2]<<"<";
    for(int i=0;i<=k;i++)
      ansf=min(ansf,ans[(1<<(k+1))-1][i]+d[p[i]][n]);
    g<<ansf<<'\n';
    f.close ();
    g.close ();
    return 0;
}