Cod sursa(job #1127566)

Utilizator dumitrualexAlex Dumitru dumitrualex Data 27 februarie 2014 12:55:57
Problema Ubuntzei Scor 35
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#define nmax 2000+5
#define kmax 17+5
#define inf 1 << 30
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 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);
            }
        }
    }
}

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

    if (prieteni.size() == 2)
    {
        printf("%d\n", pas[prieteni[0]][prieteni[1]]);
    }
    else
    {
        distMin = inf;
        do
        {
            dist = 0;
            for (i = 0; i < prieteni.size()-1; i++)
                dist += pas[prieteni[i]][prieteni[i+1]];
            distMin = min(distMin, dist);
        } while (next_permutation(prieteni.begin()+1, prieteni.end()-1));
        printf("%d\n", distMin);
    }
}
int main()
{
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);

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