Cod sursa(job #1607878)

Utilizator emanuel_rRamneantu Emanuel emanuel_r Data 21 februarie 2016 17:46:02
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<iterator>

using namespace std;

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

vector <pair <int, int> > G[2005];
vector <int> GT[40];
int Heap[2005], A[2005], D[2005], C[20][20], L[20];
int DP[262145][20];
int n, m, k, Heap_Size;
int const oo = 1000000000;

void citire()
{
    int i, x, y, c;
    f>>n>>m>>k;
    for(i=1; i <= k; i++){
        f>>L[i];
    }
    L[0] = 1;
    L[k+1] = n;
    k = k + 2;
    for(i=1; i<=m; i++){
        f>>x>>y>>c;
        G[x].push_back(make_pair(y, c));
        G[y].push_back(make_pair(x, c));
    }
}

void Swap(int hnod1, int hnod2)
{
    swap(Heap[hnod1], Heap[hnod2]);
    swap(A[Heap[hnod2]], A[Heap[hnod1]]);
}

void UpHeap(int nod)
{
    int tata = nod / 2;
    if(tata && D[Heap[nod]] < D[Heap[tata]]){
        Swap(nod, tata);
        UpHeap(tata);
    }
}

void DownHeap(int nod)
{
    int son = 2*nod;
    if(son+1 <= Heap_Size && D[Heap[son + 1]] < D[Heap[son]])
        son++;
    if(son <= Heap_Size && D[Heap[son]] < D[Heap[nod]]){
        Swap(nod, son);
        DownHeap(son);
    }
}

void Dijkstra(int start)
{

    int i, nod, vecin, cost;
    vector <pair <int, int> > ::iterator it;
    nod = L[start];

    for(i=1; i<=n; i++){
        D[i] = oo;
    }
    D[nod] = 0;
    Heap_Size = 0;

    for(i=1; i<=n; i++){
        Heap[++Heap_Size] = i;
        A[i] = Heap_Size;
        UpHeap(Heap_Size);
    }

    for(i=1; i<=n; i++){
        nod = Heap[1];
        Swap(1, Heap_Size--);
        DownHeap(1);
        for(it = G[nod].begin(); it != G[nod].end(); it++){
            vecin = it -> first;
            cost = it -> second;
            if(D[nod] + cost < D[vecin]){
                D[vecin] = D[nod] + cost;
                UpHeap(A[vecin]);
            }
        }
    }

    for(i=0; i<k; i++)
        if(i != start){
            GT[i].push_back(start);
            C[start][i] = D[L[i]];
        }
}

void hamilton()
{
    int i, nod, j, vecin, mini = oo;
    vector <int> ::iterator it;

    for(i=1; i<(1<<k); i++)
        for(j=0; j<k; j++)
            DP[i][j] = oo;
    DP[1][0] = 0;
    for(i=1; i<(1<<k); i++)
        for(nod=0; nod<k; nod++)
            if(i & (1<<nod))
                for(it = GT[nod].begin(); it != GT[nod].end(); it++){
                    vecin = *it;
                    if(i & (1<<vecin))
                        DP[i][nod] = min(DP[i][nod], DP[i ^ (1<<nod)][vecin] + C[vecin][nod]);
                }

    g<<DP[(1<<k) - 1][k-1]<<"\n";
}

int main()
{
    citire();
    for(int i=0; i<k; i++)
        Dijkstra(i);
    hamilton();
    return 0;
}