Cod sursa(job #1904886)

Utilizator delia_99Delia Draghici delia_99 Data 5 martie 2017 20:32:14
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <cstdio>
#include <vector>
#include <queue>
#define PII pair <int, int>
#include <algorithm>

using namespace std;

const int KMAX=15;
const int NMAX=2000;
const int inf=2e9;

int n,m,k,i,j;
int town[KMAX+5],D[NMAX+5],distt[KMAX+5][KMAX+5],dp[KMAX+5][1<<(KMAX+1)+5];
bool used[NMAX+5];
vector < PII > G[NMAX+5];
priority_queue < PII, vector<PII>, greater <PII> > H;

void dijkstra(int node,int ind)
{
    int i,s,son,cost;
    for(i=1; i<=n; ++i)
        D[i]=inf,used[i]=0;

    D[node]=0;
    H.push(make_pair(0,node));
    while(!H.empty())
    {
        node=H.top().second;
        H.pop();
        if(used[node]==1)
            continue;
        used[node]=1;
        s=G[node].size();

        for(i=0; i<s; ++i)
        {
            son=G[node][i].first;
            cost=G[node][i].second;

            if(D[node]+cost<D[son])
            {
                D[son]=D[node]+cost;
                H.push(make_pair(D[son],son));
            }
        }
    }

    for(i=0; i<=k; ++i)
    {
        distt[i][ind]=min(distt[i][ind],D[town[i]]);
        distt[ind][i]=distt[i][ind];
    }
}

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",&town[i]);
    town[++k]=n;
    town[0]=1;

    for(i=0; i<=k; ++i)
        for(j=0; j<=k; ++j)
            distt[i][j]=inf;

    for(i=1; i<=m; ++i)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        G[x].push_back(make_pair(y,z));
        G[y].push_back(make_pair(x,z));
    }

    for(i=0; i<=k; ++i)
        dijkstra(town[i],i);

    for(i=0; i<=k; ++i)
        for(j=0; j<(1<<(k+1)); ++j)
            dp[i][j]=inf;

    dp[0][1]=0;
    for(j=1; j<(1<<(k+1)); ++j)
        for(i=0; i<=k; ++i)
            if((j>>i)&1)
                for(int b=0; b<=k; ++b)
                    if(b!=i && ((j>>i)&1))
                        dp[i][j]=min(dp[i][j],dp[b][j^(1<<i)]+distt[b][i]);

   printf("%d\n",dp[k][(1<<(k+1))-1]);

    return 0;
}