Cod sursa(job #784795)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 6 septembrie 2012 21:50:09
Problema Ubuntzei Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

#define MAX 2048
#define KMAX 17
#define pb push_back
#define mp make_pair
#define INF 0x3f3f3f3f

using namespace std;

vector< pair < int , int > > v[MAX];
int n, m, k, a, b, c, p[KMAX], dist[KMAX][MAX], dp[(1 << KMAX)][KMAX];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;

void citire()
{
    ifstream in("ubuntzei.in");
    in>>n>>m>>k;
    for(int i = 0; i < k; i++) in>>p[i];
    for(int i = 0; i < m; i++)
    {
        in>>a>>b>>c;
        v[a].pb(mp(b, c));
        v[b].pb(mp(a, c));
    } in.close();
}

void dijkstra(int nod, int poz)
{
    memset(dist[poz], INF, MAX * sizeof(int));
    q.push(mp(0, nod));
    dist[poz][nod] = 0;
    while(!q.empty())
    {
        pair< int , int > act = q.top(); q.pop();
        int nd = act.second, dest, cost;
        for(int i = 0; i < v[nd].size(); i++)
        {
            dest = v[nd][i].first; cost = v[nd][i].second;
            if(dist[poz][dest] > dist[poz][nd] + cost)
            {
                dist[poz][dest] = dist[poz][nd] + cost;
                q.push(mp(dist[poz][dest], dest));
            }
        }
    }
}

int main()
{
    citire();
    dijkstra(1, k);
    for(int i = 0; i < k; i++) dijkstra(p[i], i);
    for(int conf = 1; conf < (1 << k); conf++)
    {
        if(!(conf & (conf - 1)))
        {
            int i;
            for(i = 0; !((1 << i) & conf); i++);
            dp[conf][i] = dist[k][p[i]];
        }
        else
        {
            for(int i = 0; i < k; i++)
            {
                dp[conf][i] = 2 * INF;
                if(conf & (1 << i))
                {
                    for(int j = 0; j < k; j++)
                    {
                        if(i != j && (conf & (1 << j)))
                        {
                            dp[conf][i] = min(dp[conf][i], dp[(conf ^ (1 << i))][j] + dist[j][p[i]]);
                        }
                    }
                }
            }
        }
    }
    int minim = 2 * INF;
    for(int i = 0; i < k; i++) minim = min(minim, dp[(1 << k) - 1][i] + dist[i][n]);
    ofstream out("ubuntzei.out"); out<<minim; out.close();
    return 0;
}