Cod sursa(job #1412399)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 1 aprilie 2015 11:52:48
Problema Ubuntzei Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
int N,K,M;
const int NMax = 2005;
vector <pair <int,int> > G[NMax];
int DP[(1<<15)+5][20];
int City[20];
int D[20][NMax],NHeap;
int Heap[NMax],Poz[NMax],ind;
const int INF = 0x3f3f3f3f;
void Read()
{
    f>>N>>M;
    f>>K;
    City[0]=1;
    for(int i=1;i<=K;i++)
        f>>City[i];
    City[K+1]=N;
    for(int i=1;i<=M;i++)
    {
        int x,y,c;
        f>>x>>y>>c;
        G[x].push_back(make_pair(y,c));
        G[y].push_back(make_pair(x,c));
    }
}
void Swap(int X,int Y)
{
    swap(Heap[X],Heap[Y]);
    swap(Poz[Heap[X]],Poz[Heap[Y]]);
}
void Percolate(int X)
{
    int Father=X/2;
    if(Father>0 && D[ind][Heap[X]]<D[ind][Heap[Father]])
    {
        Swap(Father,X);
        Percolate(Father);
    }
}
void Sift(int X)
{
    int Son=X*2;
    if(Son>NHeap)
        return;
    if(Son+1<=NHeap && D[ind][Heap[Son]]>D[ind][Heap[Son+1]])
        ++Son;
    if(D[ind][Heap[X]]>D[ind][Heap[Son]])
    {
        Swap(X,Son);
        Sift(Son);
    }
}

void Dijkstra()
{
    for(int i=1;i<=N;i++)
        D[ind][i]=INF;
    D[ind][City[ind]]=0;
    NHeap=N;
    int node=City[ind];
    for(int i=1;i<=N;i++)
    {
        if(i<City[ind])
            Poz[i]=i+1;
        if(i==City[ind])
            Poz[i]=1;
        if(i>City[ind])
            Poz[i]=i;
        Heap[Poz[i]]=i;
    }
    int counter=0;
    while(counter<N)
    {
        int node=Heap[1];
        Swap(1,NHeap);
        NHeap--;
        Sift(1);
        ++counter;
        for(int i=0;i<G[node].size();i++)
        {
            int neighb=G[node][i].first;
            if(D[ind][node]+G[node][i].second<D[ind][neighb])
            {
                D[ind][neighb]=D[ind][node]+G[node][i].second;
                Percolate(Poz[neighb]);
            }
        }
    }
}

void Hamilton()
{
    K+=2;
    for(int i=1;i<(1<<K);i++)
        for(int j=0;j<K;j++)
            DP[i][j]=INF;
    DP[1][0]=0;
    for(int conf=1;conf<(1<<K);conf++)
    {
        for(int i=0;i<K;i++)
            if(conf & (1<<i)!=0)
            {
                for(int j=0;j<K;j++)
                    if(conf & (1<<j)!=0)
                        DP[conf][i]=min(DP[conf][i],DP[conf ^ (1<<i)][j]+D[i][City[j]]);
            }
    }
    int Min=INF;
    for(int j=0;j<K;j++)
        Min=min(Min,DP[(1<<K)-1][j]);
    g<<Min<<"\n";
}
int main()
{
    Read();
    for(int i=0;i<K+2;i++)
        Dijkstra(),++ind;
    Hamilton();
    return 0;
}