Cod sursa(job #891573)

Utilizator Mitza444Vidrean Mihai Mitza444 Data 25 februarie 2013 17:55:48
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
#define pp pair<int,int>
#define ff first
#define ss second
#define MAXK 19
#define MAXN 2001
#define MAXS 1<<16
#define inf 2000000000
vector < pp > v[MAXN];
int loc[MAXK],DP[MAXK][MAXS],drum[MAXK][MAXK];
int H[MAXN],poz[MAXN],d[MAXN];
int N,M,K,hp;
void build_heap(int nod){
    int i;
    for(i=1;i<=hp;i++)
        H[i]=poz[i]=i;
    if(nod!=1){
        swap(poz[nod],poz[1]);
        swap(H[nod],H[1]);
    }
}
void sift(int p){
    int son;
    do{
        son=0;
        if(2*p<=hp)
            son=2*p;
        if(son+1<=hp && d[H[son+1]]<d[H[son]])
            son++;
        if(d[H[son]]>d[H[p]])
            son=0;
        if(son){
            swap(poz[H[p]],poz[H[son]]);
            swap(H[p],H[son]);
            p=son;
        }
    }while(son);
}
void percolate(int p){
    while(p>1 && d[H[p]]<d[H[p/2]]){
        swap(poz[H[p]],poz[H[p/2]]);
        swap(H[p],H[p/2]);
        p/=2;
    }
}
int Min(){
    int key;
    key=H[1];
    swap(poz[H[1]],poz[H[hp]]);
    H[1]=H[hp--];
    sift(1);
    return key;
}
void Dijkstra(int p){
    pp aux;
    int i,j,vfmin,dmin;
    for(i=1;i<=N;i++)
        d[i]=inf;
    d[loc[p]]=0;hp=N;
    build_heap(loc[p]);
    for(i=1;i<=N;i++){
        vfmin=Min();
        dmin=d[vfmin];
        for(j=0;j<(int)v[vfmin].size();j++){
            aux=v[vfmin][j];
            if(dmin+aux.ss<d[aux.ff]){
                d[aux.ff]=dmin+aux.ss;
                percolate(poz[aux.ff]);
            }
        }
    }
    for(j=0;j<K;++j)
        drum[p][j]=d[loc[j]];
}
int main(){
    int x,y,c,i,j,t,jnou;
    freopen("ubuntzei.in","r",stdin);
    scanf("%d%d",&N,&M);
    scanf("%d",&K);
    for(i=0;i<K;++i)
        scanf("%d",&loc[i]);
    loc[K++]=1;loc[K++]=N;
    sort(loc,loc+K);
    for(i=1;i<=M;i++){
        scanf("%d%d%d",&x,&y,&c);
        v[x].push_back(make_pair(y,c));
        v[y].push_back(make_pair(x,c));
    }
    fclose(stdin);
    for(i=0;i<K;++i)
        Dijkstra(i);
    for(i=0;i<MAXK;++i)
        for(j=0;j<MAXS;++j)
            DP[i][j]=inf;
    DP[0][1]=0;
    for(j=0;j<(1<<K)-1;++j){
        for(i=0;i<K;++i){
            if(DP[i][j]!=inf){
                for(t=0;t<K;++t)
                    if((j & (1<<t))==0){
                        jnou=j+(1<<t);
                        if(DP[t][jnou]>DP[i][j]+drum[i][t])
                            DP[t][jnou]=DP[i][j]+drum[i][t];
                    }
            }
        }
    }
    freopen("ubuntzei.out","w",stdout);
    printf("%d\n",DP[K-1][(1<<K)-1]);
    fclose(stdout);
    return 0;
}