Cod sursa(job #1112718)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 19 februarie 2014 23:02:24
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.27 kb
#include <iostream>
#include <vector>
#include <bitset>
#include <utility>
#include <queue>

using namespace std;

vector<pair<int,int> > graf[2005];
int graf2[20][20];

int n,k;
int spec[20];
int dist[20][2005];
bitset<2005> viz;

struct elem
{
    int val;
};

elem make_elem(int x)
{
    elem aux;
    aux.val=x;
    return aux;
}

#define me make_elem

int unde;

bool operator<(const elem &a,const elem &b)
{
    if(dist[unde][a.val]>dist[unde][b.val])
        return 1;
    return 0;
}

priority_queue<elem> coada;
#define inf 400000005 //de mod

inline void dijkstra()
{
    //cout<<"facem dijkstra de "<<unde<<' '<<spec[unde]<<endl;
    int i,nod=spec[unde];
   // cout<<"nod e sus "<<endl;
    for(i=1;i<=n;i++)
        viz[i]=0,dist[unde][i]=inf;
    //cout<<"init viz cu 0 si dist["<<unde<<"]["<<i<<"]="<<inf<<endl;
    dist[unde][nod]=0;
    //cout<<"si pana la nod="<<nod<<" e bine "<<endl;

    coada.push(me(nod));
    //cout<<endl;
    int y;
    vector<pair<int,int> >::iterator it;
    while(!coada.empty())
    {
        y=coada.top().val;
        coada.pop();

        if(!viz[y])
        {
           // cout<<"s-a scos porcaria de y="<<y<<endl;
            viz[y]=1;
            for(it=graf[y].begin();it!=graf[y].end();it++)
            {
                //cout<<"se analizeaza muchia cu "<<it->first<<endl;
                if(dist[unde][y]+it->second<dist[unde][it->first])
                {
                    dist[unde][it->first]=dist[unde][y]+it->second;
                    coada.push(me(it->first));
                }
            }
        }
    }
}

inline void build_dist()
{
    int i;
    for(i=0;i<=k;i++)
    {
        unde=i;
        dijkstra();
    }
}

int din[20][65540];

int main()
{
    int m,i,a,b,c;
    cin>>n>>m;

    cin>>k;
    spec[0]=1;
    for(i=1;i<=k;i++)
        cin>>spec[i];

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

    build_dist();
    int j;
    /*for(i=0;i<=k;i++)
    {
        cout<<"acum il facem pe "<<spec[i]<<endl;
        for(j=1;j<=n;j++)
        {
            cout<<dist[i][j]<<' ';
        }
        cout<<endl;
    }*/

    for(j=1;j<=k;j++)
        din[j][1]=inf;
    din[0][1]=0;

    for(i=0;i<=k;i++)
        for(j=0;j<=k;j++)
            graf2[i][j]=dist[i][spec[j]];

    int l;
    for(i=2;i<(1<<(k+1));i++)
    {
        //cout<<"lucam la starea i="<<i<<endl;
        for(j=0;j<=k;j++)
        {
            din[j][i]=inf;
            if(i&(i-1))
            {
                for(l=0;l<=k;l++)
                {
                    if(i&(1<<l))
                    {
                        din[j][i]=min(din[j][i],din[l][i-(1<<j)]+graf2[j][l]);
                    }
                }
            }
            //cout<<"din["<<j<<"]["<<i<<"]="<<din[j][i]<<endl;
        }
    }

    int minim=inf,aux;

    for(i=0;i<=k;i++)
    {
        //cout<<"din["<<i<<"]="<<din[i][(1<<(k+1))-1]<<endl;
        aux=din[i][(1<<(k+1))-1]+dist[i][n];
        cout<<aux<<endl;
        if(aux<minim)
            minim=aux;
    }

    cout<<minim<<'\n';



    return 0;
}
/*
4 3
1 3
1 2 1
2 4 1
2 3 1
*/