Cod sursa(job #1114466)

Utilizator Daniel3717Aleca Daniel Adrian Daniel3717 Data 21 februarie 2014 17:34:34
Problema Ubuntzei Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.44 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

#define inf 2000000000
struct sheap
{
    int val,node;
};

bool operator < (sheap a,sheap b)
{
    if (a.val<b.val)
        return true;
    return false;
}

//must do
void init(vector <sheap> &heap)
{
    sheap ax;
    ax.val=-inf;
    ax.node=-1;
    heap.push_back(ax);
}

bool safe(vector <sheap> &heap,int pos)
{
    if (pos>=heap.size())
        return false;
    if (pos<=0)
        return false;
    return true;
}

void heapswap(vector <sheap> &heap,vector <int> &vpos,int pos1,int pos2)
{
    sheap ax;
    ax=heap[pos1];
    heap[pos1]=heap[pos2];
    heap[pos2]=ax;
    int axi;
    int node1,node2;
    node1=heap[pos1].node;
    node2=heap[pos2].node;
    axi=vpos[node1];
    vpos[node1]=vpos[node2];
    vpos[node2]=axi;
}

void heapup(vector <sheap> &heap,vector <int> &vpos,int pos)
{
    if (!safe(heap,pos))
        return;

    if (heap[pos]<heap[pos/2])
    {
        heapswap(heap,vpos,pos,pos/2);
        heapup(heap,vpos,pos/2);
    }
}

int heapmin(vector <sheap> &heap, int pos1, int pos2)
{
    if (heap[pos1]<heap[pos2])
        return pos1;
    return pos2;
}

void heapdown(vector <sheap> &heap, vector <int> &vpos, int pos)
{
    if (!safe(heap,pos*2))
        return;

    int posdown;

    if (!safe(heap,pos*2+1))
        posdown=pos*2;
    else
        posdown=heapmin(heap,pos*2,pos*2+1);

    if (heap[posdown]<heap[pos])
    {
        heapswap(heap,vpos,posdown,pos);
        heapdown(heap,vpos,posdown);
    }
}

void heapinsert(vector <sheap> &heap,vector <int> &vpos,sheap val)
{
    heap.push_back(val);
    int pos=heap.size()-1;
    vpos[val.node]=pos;
    heapup(heap,vpos,pos);
}

//delete last one
void heapdelete(vector <sheap> &heap,vector <int> &vpos)
{
    int pos=heap.size()-1;
    sheap ax=heap[pos];
    vpos[ax.node]=0;
    heap.pop_back();
}

void heapdelete(vector <sheap> &heap,vector <int> &vpos,int pos)
{
    if (!safe(heap,pos))
        return;
    int last=heap.size()-1;
    heapswap(heap,vpos,pos,last);
    heapdelete(heap,vpos);
    if (!safe(heap,pos))
        return;
    heapup(heap,vpos,pos);
    heapdown(heap,vpos,pos);
}

void heapupdate(vector <sheap> &heap, vector <int> &vpos, int pos, sheap arg)
{
    heap[pos]=arg;
    heapup(heap,vpos,pos);
    heapdown(heap,vpos,pos);
}

class dijkstra
{
    private:vector <sheap> heap;
    private:vector <int> vpos;
    public:vector <int> dist;
    dijkstra(int nrnodes)
    {
        heap.clear();
        vpos.clear();
        dist.clear();
        init(heap);
        for (int i=0;i<nrnodes;i++)
        {
            vpos.push_back(0);
            dist.push_back(inf);
        }
    }
    bool add_or_update(sheap upd)
    {
        if (upd.node>=vpos.size())
            return false;
        if (upd.node<0)
            return false;
        int node=upd.node;
        dist[node]=upd.val;
        if (vpos[node]==0)
            heapinsert(heap,vpos,upd);
        else
            heapupdate(heap,vpos,vpos[node],upd);
        return true;
    }
    bool topdelete()
    {
        if (heap.size()<=1)
            return false;
        heapdelete(heap,vpos,1);
        return true;
    }
    sheap top()
    {
        return heap[1];
    }
    bool empty()
    {
        if (heap.size()<=1)
            return true;
        return false;
    }
};

////intermission////

#define maxn 20005

sheap axs;
int m,n,k,i,nr,a,b,c,now,dnow,to,dnowto,i1;
vector <int> orase;
vector <pair <int,int> > muchii[maxn];
int md[20][20];

int mymap[300000][20];

int go(int mask,int last)
{
    int i;
    if (mymap[mask][last]!=0)
        return mymap[mask][last];
    if (mask==0)
    {
        if (last==0)
            return 0;
        else
            return inf;
    }

    int d=inf;
    int axmask=0;

    for (i=0;(1<<i)<=mask;i++)
    {
        if (i!=last)
            if (((1<<i)&mask)!=0)
            {
                axmask=mask-(1<<i);
                d=min(d,go(axmask,i)+md[i][last]);
            }
    }

    mymap[mask][last]=d;
    return d;
}




int main(void)
{
    FILE * f;
    f=fopen("ubuntzei.in","r");
    ofstream g("ubuntzei.out");
    fscanf(f,"%d%d%d",&n,&m,&k);
    orase.push_back(1);
    for (i=1;i<=k;i++)
    {
        fscanf(f,"%d",&nr);
        orase.push_back(nr);
    }
    orase.push_back(n);
    for (i=1;i<=m;i++)
    {
        fscanf(f,"%d%d%d",&a,&b,&c);
        muchii[a].push_back(make_pair(b,c));
        muchii[b].push_back(make_pair(a,c));
    }

    dijkstra d(n+1);

    for (i=0;i<orase.size();i++)
    {
        d=dijkstra(n+1);

        axs.node=orase[i];
        axs.val=0;
        d.add_or_update(axs);

        while (!d.empty())
        {
            now=d.top().node;
            dnow=d.top().val;
            for (i1=0;i1<muchii[now].size();i1++)
            {
                to=muchii[now][i1].first;
                dnowto=muchii[now][i1].second;
                if (dnow+dnowto<d.dist[to])
                {
                    axs.val=dnow+dnowto;
                    axs.node=to;
                    d.add_or_update(axs);
                }
            }
            d.topdelete();
        }

        for (i1=0;i1<orase.size();i1++)
            md[i][i1]=d.dist[orase[i1]];
    }


    k=k+2;
    g<<go((1<<k)-1,k);

    return 0;

}