Cod sursa(job #2017798)

Utilizator danstefanDamian Dan Stefan danstefan Data 2 septembrie 2017 16:14:47
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
int ans2,c[20],n,k,m,dp[(1<<17)][20],drum[20][20],ans[2010],x,y,z,i,j,l;
vector <pair<int,int> >g[2010];
bool ap[2010];
void dijkstra(int s)
{
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >pq;
    pq.push({0,c[s]});
    memset(ap,0,sizeof(ap));
    memset(ans,inf,sizeof(ans));
    ans[c[s]]=0;
    while(!pq.empty())
    {
        int  cst=pq.top().first;
        int  node=pq.top().second;
        pq.pop();
        if(ap[node])continue;
        ap[node]=true;
        for(auto&it:g[node])
            if(ans[it.first]>ans[node]+it.second)
            {
                ans[it.first]=ans[node]+it.second;
                pq.push({ans[it.first],it.first});
            }
    }
    for(int i=0;i<=k;++i)
    {
        drum[s][i]=ans[c[i]];
        if(s==0 && i!=s && i!=k)dp[1<<(i-1)][i]=ans[c[i]];
    }
}
int main()
{
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=k;++i)
        scanf("%d",&c[i]);
        c[0]=1;
    c[++k]=n;
    for(i=1;i<=m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        g[x].push_back({y,z});
        g[y].push_back({x,z});
    }
    int loc=(1<<(k-1));
    for(i=1;i<loc;++i)
        for(j=1;j<k;++j)
            dp[i][j]=inf;
    for(i=0;i<=k;++i)
        dijkstra(i);
    --k;
    for(i=1;i<loc;++i)
    {
        for(j=1;j<=k;++j)
            if(i&(1<<(j-1)))
            {
                for(l=1;l<=k;++l)
                if((i&(1<<(l-1)))&&l!=j)dp[i][j]=min(dp[i][j],dp[i-(1<<(j-1))][l]+drum[l][j]);
            }
    }
    if(k==0)
    {
        printf("%d\n",drum[0][k+1]);
        return 0;
    }
    ans2=inf;
    for(i=1; i<=k; ++i)
        ans2=min(ans2,dp[loc-1][i]+drum[i][k+1]);
    printf("%d\n",ans2);
}