Cod sursa(job #1009478)

Utilizator crisbodnarCristian Bodnar crisbodnar Data 13 octombrie 2013 12:00:22
Problema Ubuntzei Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>

#define ff first
#define ss second
#define newn a[x.ss][i].ss
#define cost a[x.ss][i].ff

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

const int N = 2005;
const int K = 16;
const int oo = 0x3f3f3f3f;

int n, m, k, c[K], dp[(1<<K)][K], dist[K][N], d0[N];
typedef pair <int, int> nod;
vector <nod> a[N];
priority_queue<nod, vector<nod>, greater<nod> > h;

void Dijkstra(const int s, int *dis)
{
    for(int i=1; i<=n; i++)
        dis[i] = oo;
    dis[s] = 0; h.push(nod(0, s));
    while(!h.empty())
    {
        nod x = h.top(); h.pop();
        if(x.ff > dis[x.ss]) continue;

        for(unsigned i=0; i<a[x.ss].size(); i++)
            if(dis[x.ss] + cost < dis[newn])
            {
                dis[newn] = dis[x.ss] + cost;
                h.push(nod(dis[newn], newn));
            }
    }
}

inline bool In(int biti, int bit)
{
    return ((1<<bit) & biti);
}

int main()
{
    fin>>n>>m>>k;
    for(int i=0; i<k; i++)
        fin>>c[i];

    for(int i=1; i<=m; i++)
    {
        int x, y, z;
        fin>>x>>y>>z;
        a[x].push_back(nod(z, y));
        a[y].push_back(nod(z, x));
    }

    Dijkstra(1, d0);
    if(!k)
    {
        fout<<dist[n];
        return 0;
    }

    for(int i=0; i<k; i++)
        Dijkstra(c[i], dist[i]);

    for(int i=1; i<(1<<k); i++)
    {
        bool ok = 0;
        for(int j=0; j<k; j++)
            if(i == (1<<j))
            {
                dp[i][j] = d0[c[j]];
                ok = 1; break;
            }
        if(ok) continue;

        for(int j=0; j<k; j++)
        {
            dp[i][j] = oo;
            if(In(i, j))
                for(int jj=0; jj<k; jj++)
                    if(j != jj && In(i, jj))
                        dp[i][j] = min(dp[i][j], dp[i-(1<<j)][jj] + dist[jj][c[j]]);
        }
    }

    int sol = oo;
    for(int i=0; i<k; i++)
        sol = min(sol, dp[(1<<k)-1][i] + dist[i][n]);
    fout<<sol;
    return 0;
}