Cod sursa(job #877799)

Utilizator VisuianMihaiMihai Visuian VisuianMihai Data 13 februarie 2013 11:00:46
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include <fstream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
vector<pair<int,int> >g[2001];
queue<int>q;
int drum[17][2001], c[17], sol[(1<<17)][17],n, m, k, x, y, co;

int last_sol(int x, int next)
{
    if ( !x )
        return drum[0][next];
    int minx = 999999999;
    for(int ind = 0; ind < k; ind++)
        if((x & (1<<ind)) == (1<<ind))
            if(minx > sol[x][ind] + drum[ind+1][next])
                minx = sol[x][ind] + drum[ind+1][next];
    return minx;
}
int main()
{
    fin >> n >> m;
    fin>>k;
    c[0]=1;
    for ( int i = 1; i <= k; i++ )
        fin >> c[i];
    for ( int i = 1; i <= m; i++ )
    {
        fin >> x >> y >> co;
        g[x].push_back(make_pair(y,co));
        g[y].push_back(make_pair(x,co));
    }

    for(int i=0;i<=k;i++)
        for(int j=1;j<=n;j++)
            drum[i][j] = 999999999;
    for (int i = 0; i <= k; i++ )
    {
        q.push(c[i]);
        drum[i][c[i]]=0;
        while ( !q.empty() )
        {
            int curent = q.front();
            for ( size_t d = 0; d < g[curent].size(); d++)
            {
                if ( drum[i][g[curent][d].first] > drum[i][curent]+g[curent][d].second)
                {
                    drum[i][g[curent][d].first] = drum[i][curent]+g[curent][d].second;
                    q.push(g[curent][d].first);
                }
            }
            q.pop();
        }
    }
    for ( int i = 1; i <= (1<<k); i++ )
    {
        for ( int ind = 0; ind < k; ind++ )
        {
            if ( (i & (1<<ind)) == (1<<ind) )
            {
                sol[i][ind]=last_sol(i-(1<<ind),c[ind+1]);
            }
        }
    }
    fout << last_sol((1<<k)-1, n);
    fin.close();
    fout.close();
    return 0;
}