Cod sursa(job #1535244)

Utilizator livliviLivia Magureanu livlivi Data 24 noiembrie 2015 15:09:43
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include<cstdio>
#include<queue>
#define N 2000
#define M 10000
#define K 15
#define MULT (1<<31)-1
using namespace std;

int urm[2*M+1];
int lst[N+1];
int vecin[2*M+1];
int cost[M+1];

class mazi{
public:
    int dist;
    int dest;

    bool operator < (const mazi a) const{
        if (a.dist<dist) return true;
        return false;
    }
    bool operator > (const mazi a) const{
        if (a.dist>dist) return true;
        return false;
    }
};

mazi chestie(int a,int b){
    mazi r;
    r.dist=b;
    r.dest=a;
    return r;
}


priority_queue <mazi> heap;

int viz[N+1];
int muchii[K+2][K+2];
int dp[1<<(K+2)][K+2];

int pr[K+2];
int id[N+1];

int k,n;

void adauga(int i,int n1,int n2){
    vecin[i*2-1]=n2;
    urm[i*2-1]=lst[n1];
    lst[n1]=i*2-1;

    vecin[i*2]=n1;
    urm[i*2]=lst[n2];
    lst[n2]=i*2;
}


void avanseaza(){
    mazi a;
    a=heap.top();
    while(viz[a.dest]!=-1 &&(!heap.empty())){
        heap.pop();
        if (!heap.empty())a=heap.top();
    }
}

void djikstra(int nod){
    mazi curent;
    int p,i;
    heap.push(chestie(nod,0));

    for(i=1;i<=n;i++)
        viz[i]=-1;

    while(!heap.empty()){
        curent=heap.top();
        viz[curent.dest]=curent.dist;
        heap.pop();

        avanseaza();

        p=lst[curent.dest];
        while(p>0){
            if (viz[vecin[p]]==-1){
                heap.push(chestie(vecin[p],curent.dist+cost[(p+1)/2]));
            }
            p=urm[p];
        }

        avanseaza();
    }

    for(i=0;i<=k+1;i++){
        muchii[id[nod]][i]=viz[pr[i]];
        muchii[i][id[nod]]=viz[pr[i]];
    }
}

int drum(){
    int i,j,l;
    int lim=(1<<(k+2));
    int mask;

    for(i=0;i<lim;i++)
        for(j=0;j<=k+1;j++)
            dp[i][j]=-1;

    dp[1][0]=0;
    for(i=0;i<lim;i++)
        for(j=0;j<=k+1;j++)
            if ((1<<j)&i){
                mask=(1<<j)^i;
                for(l=0;l<=k+1;l++)
                    if ((1<<l)&mask){
                        if ((dp[i][j]>dp[mask][l]+muchii[l][j] ||dp[i][j]==-1) &&dp[mask][l]!=-1 &&muchii[l][j]!=0) dp[i][j]=dp[mask][l]+muchii[l][j];
                    }
            }
    return dp[lim-1][k+1];
}

int main(){
    freopen ("ubuntzei.in","r",stdin);
    freopen ("ubuntzei.out","w",stdout);
    int m,i,x,y;

    scanf ("%d%d%d",&n,&m,&k);

    pr[0]=1;
    pr[k+1]=n;
    id[1]=0;
    id[n]=k+1;
    for(i=1;i<=k;i++){
        scanf ("%d",&pr[i]);
        id[pr[i]]=i;
    }

    for(i=1;i<=m;i++){
        scanf ("%d%d%d",&x,&y,&cost[i]);
        adauga(i,x,y);
    }

    for(i=0;i<=k+1;i++)
        djikstra(pr[i]);

    printf ("%d",drum());
    return 0;
}