Cod sursa(job #1127790)

Utilizator dumitrualexAlex Dumitru dumitrualex Data 27 februarie 2014 13:50:44
Problema Ubuntzei Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.8 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#define nmax 2000+5
#define kmax 17+5
#define inf 1 << 29
using namespace std;


struct muchie
{
    int destinatie, distanta;

    muchie(int destinatie = 0, int distanta = 0): destinatie(destinatie), distanta(distanta)
    {

    }
};

vector<muchie> graf[nmax];
vector<int> prieteni;
int pas[nmax][nmax];
int cost[kmax][(1<<kmax)];
int n, m, k;
int startDijkstra;

struct cmp
{
    bool operator()(const int & a, const int & b)
    {
        return pas[startDijkstra][a] > pas[startDijkstra][b];
    }
};

priority_queue<int, vector<int>, cmp> heap;

void citire()
{
    int i, x, y, c;
    scanf("%d%d%d", &n, &m, &k);

    prieteni.push_back(1);
    for (i = 1; i <= k; i++)
    {
        scanf("%d", &x);
        prieteni.push_back(x);
    }
    prieteni.push_back(n);

    for (i = 1; i <= m; i++)
    {
        scanf("%d%d%d", &x, &y, &c);
        graf[x].push_back(muchie(y, c));
        graf[y].push_back(muchie(x, c));
    }
}

void dijkstra()
{
    int i;
    int curent;
    int pasT;
    muchie vecin;

    for (i = 1; i <= n; i++)
        pas[startDijkstra][i] = inf;
    pas[startDijkstra][startDijkstra] = 0;

    heap.push(startDijkstra);

    while (!heap.empty())
    {
        curent = heap.top();
        heap.pop();

        for (i = 0; i < graf[curent].size(); i++)
        {
            vecin = graf[curent][i];

            pasT = pas[startDijkstra][curent] + vecin.distanta;
            if (pasT < pas[startDijkstra][vecin.destinatie])
            {
                pas[startDijkstra][vecin.destinatie] = pasT;
                heap.push(vecin.destinatie);
            }
        }
    }
}

int memo(int lin, int col)
{
    int i;
    int costT;
    if (cost[lin][col] == 0)
    {
        cost[lin][col] = inf;
        if (lin > 0 && (col - (1 << lin)) > 0)
            for (i = 0; i < prieteni.size(); i++)
                if (i != lin)
                {
                    costT = memo(i, col - (1 << lin));
                    costT += pas[prieteni[i]][prieteni[lin]];
                    cost[lin][col] = min(cost[lin][col],  costT);
                }
    }
    return cost[lin][col];
}

void rezolvare()
{
    int i;
    int dist, distMin;
    for (i = 0; i < prieteni.size(); i++)
    {
        startDijkstra = prieteni[i];
        dijkstra();
    }

    for (i = 1; i < prieteni.size(); i++)
    {
        cost[i][(1<<i) + 1] = pas[prieteni[0]][prieteni[i]];
    }
}

void afisare()
{
    printf("%d\n", memo(prieteni.size()-1, (1<<(prieteni.size())) - 1));
}



int main()
{
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);

    citire();
    rezolvare();
    afisare();
    return 0;
}