Cod sursa(job #785100)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 7 septembrie 2012 19:44:27
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define nod first
#define cost second
#define NM 2010
#define KM 20
#define DM 33768
#define INF 0x3f3f3f3f

using namespace std;

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

typedef pair<int, int> PI;

struct Queue_CMP
{
    bool operator () (const PI& a, const PI& b) const
    {
        return a.cost>b.cost;
    }
};

priority_queue <PI, vector<PI>, Queue_CMP> Q;
vector<PI> G[NM];

int N,M,K,i,j,k,a,b,c;
int KNod[KM];
int DJ[KM][NM];
int ANS=INF;
int CM[KM][KM];
int PW[KM];
int HM[KM][DM];

void Read ()
{
    f >> N >> M >> K;

    KNod[0]=1;
    for (i=1; i<=K; i++)
        f >> KNod[i];

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

    f.close();
}

void DoDijkstra (int k)
{
    memset(DJ[k],INF,sizeof(DJ[k]));

    DJ[k][KNod[k]]=0;
    Q.push(make_pair(KNod[k],0));

    int nod,cost,ncost,nnod;
    unsigned int i;

    while (!Q.empty())
    {
        nod=Q.top().nod;
        cost=Q.top().cost;
        Q.pop();
        if (cost!=DJ[k][nod]) continue;

        for (i=0; i<G[nod].size(); i++)
        {
            nnod=G[nod][i].nod;
            ncost=G[nod][i].cost+cost;

            if (DJ[k][nnod]<=ncost) continue;

            DJ[k][nnod]=ncost;
            Q.push(make_pair(nnod,ncost));
        }
    }
}

void DoHamilton ()
{
    for (PW[0]=1,i=1; i<KM; i++)
        PW[i]=2*PW[i-1];

    int NP=PW[K];

    memset(HM,INF,sizeof(HM));

    for (i=1; i<=K; i++)
        HM[i][PW[i-1]]=DJ[i][1];

    for (i=1; i<NP-1; i++)
        for (j=1; j<=K; j++)
            if ((i&PW[j-1]))
                for (k=1; k<=K; k++)
                    if ((i&PW[k-1])==0 && CM[j][k]!=INF)
                        HM[k][i|PW[k-1]]=min(HM[k][i|PW[k-1]], HM[j][i]+CM[j][k]);

    for (i=1; i<=K; i++)
        ANS=min(ANS,HM[i][NP-1]+DJ[i][N]);

}

void Solve ()
{
    for (i=0; i<=K; i++)
        DoDijkstra(i);
    memset(CM,INF,sizeof(CM));

    if (K==0) ANS=DJ[0][N];
    for (i=1; i<=K; i++)
        for (j=1; j<=K; j++)
                CM[i][j]=DJ[i][KNod[j]];

    DoHamilton();
}

void Print ()
{
    g << ANS << '\n';
    g.close();
}

int main ()
{
    Read();
    Solve();
    Print();
    return 0;
}