Cod sursa(job #2168677)

Utilizator eragon0502Dumitrescu Dragos eragon0502 Data 14 martie 2018 11:56:30
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int INF = 200000000;

vector < pair <int,int> > v[2005];
int k[20],ck[20][20],c[2005],viz[2005],h[2005],poz[2005],d[1<<18][18],siz=0,n,m,K;

void swapp(int p1, int p2){
    swap(h[p1],h[p2]);
    poz[h[p1]]=p1;
    poz[h[p2]]=p2;
}

void upheap(int p){
    if(p>1&&c[h[p]]<c[h[p/2]]){
        swapp(p,p/2);
        upheap(p/2);
    }
}

void downheap(int p){
    int aux=p;
    if(2*p<=siz&&c[h[aux]]>c[h[2*p]])
        aux=2*p;
    if(2*p+1<=siz&&c[h[aux]]>c[h[2*p+1]])
        aux=2*p+1;
    if(aux!=p){
        swapp(aux,p);
        downheap(aux);
    }
}

void add(int nod,int cost){
    if(viz[nod]==0){
        h[++siz]=nod;
        poz[nod]=siz;
        viz[nod]=1;
        c[nod]=cost;
        upheap(siz);
    }
    else
    {
        if(c[nod]>cost){
            c[nod]=cost;
            upheap(poz[nod]);
        }
    }
}

void del(int p){
    swapp(p,siz);
    --siz;
    downheap(p);
}

void resett(){
    for(int i=1;i<=n;++i){
        viz[i]=c[i]=h[i]=poz[i]=0;
        siz=0;
    }
}

int main()
{
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    int x,y,cs,top,nod,cost,ii;
    scanf("%d %d %d ",&n,&m,&K);
    for(int i=1;i<=K;++i)
        scanf("%d ",&k[i]);
    K+=2;
    k[K-1]=1;
    k[K]=n;
    sort(k+1,k+K+1);
    for(int i=1;i<=m;++i){
        scanf("%d %d %d",&x,&y,&cs);
        v[x].push_back(make_pair(y,cs));
        v[y].push_back(make_pair(x,cs));
    }
    for(int t=1;t<=K;++t){
        add(k[t],0);
        while(siz>0){
            top=h[1];
            del(1);
            for(int j=0;j<v[top].size();++j){
                nod=v[top][j].first;
                cost=v[top][j].second+c[top];
                add(nod,cost);
            }
        }
        for(int i=1;i<=K;++i){
            if(i!=t)
                ck[t][i]=c[k[i]];
        }
        resett();
    }

    for(int i=0;i<K;++i){
        for(int j=0;j<K;++j)
            ck[i][j]=ck[i+1][j+1];
        k[i]=k[i+1];
    }
    for(int i=0;i<=(1<<K)-1;++i)
        for(int j=0;j<=K;++j)
            d[i][j]=INF;
    d[1][0]=0;
    for(int i=3;i<=(1<<K)-1;i+=2){
        for(int j=1;j<K;++j){
            if((1<<j)&i){
                ii=i-(1<<j);
                for(int t=0;t<K;++t){
                    if((1<<t)&ii){
                        d[i][j]=min(d[i][j],d[ii][t]+ck[t][j]);
                    }
                }
            }
        }
    }
    printf("%d",d[(1<<K)-1][K-1]);
    return 0;
}