Cod sursa(job #581480)

Utilizator darrenRares Buhai darren Data 14 aprilie 2011 11:24:58
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.52 kb
#include <fstream>
#include <set>
#include <vector>

using namespace std;

#define push_pair(def1, def2) push_back(make_pair(def1, def2))
typedef vector<pair<int, int> > VP;

const int INF = 0x3f3f3f3f;

int preLog[1 << 16];
int N, M, K;
int C[16], minC[1 << 16][16];
int cost[16][2002];
VP V[2002];
set<pair<int, int> > S;

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

    preLog[1] = 1;
    for (int i = 2; i < 1 << 16; ++i)
        preLog[i] = preLog[i >> 1] + 1;

    fin >> N >> M >> K;
    for (int i = 1; i <= K; ++i)
        fin >> C[i];
    for (int i = 1, nod1, nod2, cost; i <= M; ++i)
    {
        fin >> nod1 >> nod2 >> cost;
        V[nod1].push_pair(nod2, cost);
        V[nod2].push_pair(nod1, cost);
    }

    for (int ind = 1; ind <= K; ++ind) // calculeaza costurile
    {
        int now = C[ind];

        for (int i = 1; i <= N; ++i)
            if (i != now) cost[ind][i] = INF;
        for (VP::iterator it = V[now].begin(); it != V[now].end(); ++it)
            cost[ind][it->first] = it->second;

        for (int i = 1; i <= N; ++i)
            if (i != now)
                S.insert(make_pair(cost[ind][i], i));

        while (!S.empty())
        {
            int nod = (*S.begin()).second, costnow = (*S.begin()).first;
            S.erase(S.begin());

            if (costnow > cost[ind][nod]) continue;

            for (VP::iterator it = V[nod].begin(); it != V[nod].end(); ++it)
                if (costnow + it->second < cost[ind][it->first])
                {
                    cost[ind][it->first] = costnow + it->second;
                    S.insert(make_pair(cost[ind][it->first], it->first));
                }
        }
    }

    for (int i = 1; i < (1 << K); ++i)
    {
        int aux = i, now;
        while (aux)
        {
            now = aux & -aux;
            minC[i][preLog[now]] = INF;

            int aux2 = i ^ now, now2;

            if (aux2 == 0) minC[i][preLog[now]] = cost[preLog[now]][1];
            while (aux2)
            {
                now2 = aux2 * -aux2;

                minC[i][preLog[now]] = min(minC[i][preLog[now]], minC[i ^ now][preLog[now2]] + cost[preLog[now]][C[preLog[now2]]]);

                aux2 &= aux2 - 1;
            }

            aux &= aux - 1;
        }
    }

    int result = INF;
    for (int i = 1; i <= K; ++i)
        result = min(result, minC[(1 << K) - 1][i] + cost[i][N]);

    fout << result;

    fin.close();
    fout.close();
}