Cod sursa(job #1281422)

Utilizator serban_ioan97Ciofu Serban serban_ioan97 Data 3 decembrie 2014 09:44:15
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <cstdio>
#include <vector>
#include <cstring>
#define pb push_back
#include <queue>
#define inf 1061109567
#define nmax 2002
#include <algorithm>

using namespace std;

vector<pair<int, int> > a[nmax];
queue<int> q;

int n, k, m, i;
int dist[nmax], order[nmax];
int dp[1<<16][16];
int dmin[nmax][nmax];

void dijkstra(int sursa)
{
    bool used[nmax];
    queue <int> q;

    memset(used, false, sizeof(used));
    memset(dist, inf, sizeof(dist));

    dist[sursa]=0; q.push(sursa); used[sursa]=true;
    while(!q.empty())
    {
        int nod=q.front(); q.pop();
        used[nod]=false;

        for(vector<pair <int, int> >::iterator it=a[nod].begin(); it!=a[nod].end(); ++it)
        if (dist[nod]+it->second<dist[it->first])
        {
            dist[it->first]=dist[nod]+it->second;
            if(!used[it->first])
            {
                q.push(it->first);
                used[it->first]=true;
            }
        }
    }
}
int main()
{
    freopen("ubuntzei.in", "rt", stdin);
    freopen("ubuntzei.out", "wt", stdout);

    scanf("%d%d", &n, &m);
    scanf("%d", &k);

    for(i=1; i<=k; ++i)
    scanf("%d", &order[i]);

    int x, y, cost;

    for(i=1; i<=m; ++i)
    {
        scanf("%d%d%d", &x, &y, &cost);
        a[x].pb(make_pair(y, cost));
        a[y].pb(make_pair(x, cost));
    }


    if(!k)
    {
        dijkstra(1);
        printf("%d", dist[n]);
    }
    else
    {
        order[0]=1;
        for(i=0; i<=k; ++i)
        {
            dijkstra(order[i]);
            for(int j=0; j<=k; ++j)
            dmin[i][j]=dist[order[j]];
            dmin[i][k+1]=dist[n];
        }

        int lim=(1<<k);
        for(int q=0; q<lim; ++q)
            for(i=0; i<=k; ++i)
                dp[q][i]=inf;

        dp[0][0]=0;

        for(int q=1; q<lim; ++q)
            for(i=0; i<k; ++i)
            if(q&(1<<i))
            {
                int qq=q-(1<<i);
                for(int j=0; j<=k; ++j)
                dp[q][i+1]=min(dp[q][i+1], dp[qq][j]+dmin[j][i+1]);
            }

            int sol=inf;

            for(i=1; i<=k; ++i)
            sol=min(sol, dp[lim-1][i]+dmin[i][k+1]);

            printf("%d", sol);
    }

    return 0;
}