Cod sursa(job #991511)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 30 august 2013 16:58:37
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <fstream>
#include <vector>
#include <utility>

#define vint vector<pair<int,int> >::iterator
#define inf 1000000000
#define maxn 2010
#define cost second
#define x first

using namespace std;

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

vector<pair<int,int> > G[maxn],H[maxn];
int d[maxn],h[maxn],hpoz[maxn],v[18];
int n,m,k,a,b,c,heapsize,hamilton[1<<18][18];

inline int father (const int &x)
{
    return x>>1;
}

inline int right_son (const int &x)
{
    return x<<1;
}

inline int left_son (const int &x)
{
    return (x<<1)+1;
}

void upheap (int poz)
{
    int pullout = h[poz], current = poz;

    while (d[pullout] < d[h[father(current)]])
    {
        h[current]  =  h[father(current)];
        hpoz[h[current]] = current;
        current >>= 1;
    }

    h[current] = pullout;
    hpoz[h[current]] = current;
}

void downheap (int poz)
{
    int pullout = h[poz], current = poz, ok = 1;

    while (ok != -1)
    {
        ok=-1;
        if (d[pullout] > d[h[right_son(current)]]) ok=0;

        if (d[pullout] > d[h[left_son(current)]])
        {
            if (ok==0)
            {
                if (d[h[left_son(current)]] > d[h[right_son(current)]])
                    ok=1;
            }
            else ok=1;
        }

        if (ok!=-1)
        {
            h[current] = h[(current<<1)+ok];
            hpoz[h[current]] = current;
            current = (current<<1)+ok;
        }
    }

    h[current] = pullout;
    hpoz[h[current]] = current;
}

void dijkstra (int s)
{
    heapsize=n;

    for (int i=1; i<=n+1; ++i)
    {
        d[i]=inf;
        h[i]=i;
        hpoz[i]=i;
    }

    d[s]=0;
    swap (h[1],h[s]);
    swap (hpoz[1],hpoz[s]);

    while (d[h[1]]!=inf)
    {
        int current = h[1];

        for (vint it = G[current].begin(); it!=G[current].end(); ++it)
        {
            if (d[it->x] > d[current] + it->cost)
            {
                d[it->x] = d[current] + it->cost;
                upheap (hpoz[it->x]);
            }
        }

        h[1]=h[heapsize];
        hpoz[h[1]]=1;
        h[heapsize]=n+1;
        --heapsize;
        downheap (1);
    }
}

int main()
{
    fin>>n>>m>>k;

    v[0]=1;
    for (int i=1; i<=k; ++i) fin>>v[i];
    v[k+1]=n;
    k=k+1;

    for (int i=1; i<=m; ++i)
    {
        fin>>a>>b>>c;
        G[a].push_back (make_pair(b,c));
        G[b].push_back (make_pair(a,c));
    }

    for (int i=0; i<=k; ++i)
    {
        dijkstra (v[i]);

        for (int j=0; j<=k; ++j)
        {
            if (i==j) continue;
            H[i].push_back (make_pair(j,d[v[j]]));
        }
    }

    int nr = (1<<(k+1))-1;
    for (int i=0; i<=nr; ++i)
        for (int j=0; j<=k; ++j) hamilton[i][j] = inf;

    hamilton[1][0] = 0;

    for (int i=1; i<=nr; ++i)
    {
        for (int j=0; j<=k ; ++j)
        {
            if (hamilton[i][j]==inf) continue;
            for (vint it = H[j].begin(); it!= H[j].end(); ++it)
            {
                if ((i | (1<<it->x)) != i) if (hamilton[i | (1<<it->x)][it->x] > hamilton[i][j] + it->cost)
                                              hamilton [i | (1<<it->x)][it->x] = hamilton[i][j] + it->cost;
            }
        }
    }

    fout<<hamilton[nr][k];
}