Cod sursa(job #2388448)

Utilizator DovlecelBostan Andrei Dovlecel Data 26 martie 2019 08:50:08
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int N=2005;
const int K=17;
const int INF=1<<30;
int n,m,k,cost[K][K],v[K],d[N],dp[1<<K][K];
vector< pair<int,int> >a[N];
vector<int>meta[K];
void reset();
void update(int x);
void hamilton();
void build_meta();

void citire()
{
    in>>n>>m>>k;
    int cnt=0,x,y,c;
    for(int i=1;i<=k;i++)
    {
        in>>x;
        v[++cnt]=x;
    }
    for(int i=1;i<=m;i++)
    {
        in>>x>>y>>c;
        a[x].push_back(make_pair(y,c));
        a[y].push_back(make_pair(x,c));
    }
}

priority_queue< pair<int,int> >q;
void dijkstra(int x)
{
    int y,c;
    reset();
    d[x]=0;
    q.push(make_pair(-d[x],x));
    while(!q.empty())
    {
        while(!q.empty() && d[q.top().second]<-q.top().first)
            q.pop();
        if(q.empty())
            return;
        x=q.top().second;
        q.pop();
        for(unsigned i=0;i<a[x].size();i++)
        {
            y=a[x][i].first;
            c=a[x][i].second;
            if(d[x]+c<d[y])
            {
                d[y]=d[x]+c;
                q.push(make_pair(-d[y],y));
            }
        }
    }
}

int main()
{
    citire();
    for(int i=1;i<=k;i++)
    {
        dijkstra(i);
        update(i);
    }
    build_meta();
    hamilton();
    out<<dp[(1<<(k+1))-1][n];
    return 0;
}

void reset()
{
    for(int i=1;i<=n;i++)
        d[i]=INF;
}
void update(int x)
{
    for(int i=1;i<=k;i++)
        cost[x][v[i]]=d[i];
}
void build_meta()
{
    for(int i=1;i<=k;i++)
        for(int j=1;j<=k;j++)
            if(cost[i][j])
                meta[j].push_back(i);
    for(int i=1;i<(1<<(k+1));i++)
        for(int j=1;j<=k;j++)
            dp[i][j]=INF;
}
void hamilton()
{
    dp[1][1]=0;
    for(int i=1;i<(1<<(k+1));i++)
        for(int j=1;j<=k;j++)
            if(i&(1<<j))
                for(unsigned k=0;k<meta[j].size();k++)
                    if(i&(1<<meta[j][k]))
                        dp[i][j]=min(dp[i][j],dp[i-(1<<j)][meta[j][k]]+cost[meta[j][k]][j]);
}