Cod sursa(job #1535129)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 24 noiembrie 2015 13:09:22
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <cstdio>
#include <cctype>
#define INF 2000000000
#define BUF_SIZE 4096
#define MAXN 2000
#define MAXK 15
#define MAXM 10000
int n, q, d[1<<MAXK][MAXK], heap[MAXN], poz[MAXN+1], lista[MAXN+1], next[2*MAXM+1], val[2*MAXM+1], v[MAXK], done[MAXN+1], sol[MAXN+1], a[MAXN+1], end[MAXN+1];
int pos=BUF_SIZE, cost[2*MAXM+1], dist[MAXK][MAXK];
char buf[BUF_SIZE];
FILE *fin;
inline char nextch(){
    if(pos==BUF_SIZE){
        fread(buf, BUF_SIZE, 1, fin);
        pos=0;
    }
    return buf[pos++];
}
inline int read(){
    int x=0;
    char ch=nextch();
    while(!isdigit(ch)){
        ch=nextch();
    }
    while(isdigit(ch)){
        x=10*x+ch-'0';
        ch=nextch();
    }
    return x;
}
inline int tata(int p){
    return (p-1)/2;
}
inline int fiust(int p){
    return 2*p+1;
}
inline int fiudr(int p){
    return 2*p+2;
}
inline void swap(int p, int q){
    int aux=heap[p];
    heap[p]=heap[q];
    heap[q]=aux;
    poz[heap[p]]=p;
    poz[heap[q]]=q;
}
inline void coborare(int p){
    int q, f=1;
    while((f==1)&&(fiust(p)<n)){
        q=fiust(p);
        if((fiudr(p)<n)&&(a[heap[fiudr(p)]]<a[heap[q]])){
            q=fiudr(p);
        }
        if(a[heap[q]]<a[heap[p]]){
            swap(p, q);
            p=q;
        }else{
            f=0;
        }
    }
}
inline void urcare(int p){
    while((p>0)&&(a[heap[p]]<a[heap[tata(p)]])){
        swap(p, tata(p));
        p=tata(p);
    }
}
inline void djikstra(int s){
    int i, p;
    for(i=1; i<=n; i++){
        heap[i-1]=i;
        poz[i]=i-1;
        a[i]=INF;
        done[i]=0;
    }
    a[s]=0;
    urcare(poz[s]);
    while(a[heap[0]]!=INF){
        p=lista[heap[0]];
        while(p){
            if((done[val[p]]==0)&&(a[val[p]]>a[heap[0]]+cost[p])){
                a[val[p]]=a[heap[0]]+cost[p];
                urcare(poz[val[p]]);
            }
            p=next[p];
        }
        done[heap[0]]=1;
        sol[heap[0]]=a[heap[0]];
        a[heap[0]]=INF;
        coborare(0);
    }
}
inline void adauga(int a, int b, int c){
    q++;
    val[q]=b;
    cost[q]=c;
    next[q]=lista[a];
    lista[a]=q;
}
int main(){
    int m, i, x, y, z, j, k, p, ans;
    FILE *fout;
    fin=fopen("ubuntzei.in", "r");
    fout=fopen("ubuntzei.out", "w");
    n=read();
    m=read();
    k=read();
    for(i=0; i<k; i++){
        v[i]=read();
    }
    for(i=0; i<m; i++){
        x=read();
        y=read();
        z=read();
        adauga(x, y, z);
        adauga(y, x, z);
    }
    for(i=0; i<k; i++){
        djikstra(v[i]);
        for(j=0; j<k; j++){
            dist[i][j]=sol[v[j]];
        }
        end[i]=sol[n];
    }
    djikstra(1);
    for(i=0; i<k; i++){
        d[1<<i][i]=sol[v[i]];
    }
    for(i=1; i<(1<<k); i++){
        for(j=0; j<k; j++){
            if((i!=(1<<j))&&(i&(1<<j))){
                d[i][j]=INF;
                for(p=0; p<k; p++){
                    if((p!=j)&&(i&(1<<p))&&(d[i][j]>d[i^(1<<j)][p]+dist[j][p])){
                        d[i][j]=d[i^(1<<j)][p]+dist[j][p];
                    }
                }
            }
        }
    }
    ans=INF;
    for(i=0; i<k; i++){
        if(ans>end[i]+d[(1<<k)-1][i]){
            ans=end[i]+d[(1<<k)-1][i];
        }
    }
    if(ans==INF){
        ans=sol[n];
    }
    fprintf(fout, "%d\n", ans);
    fclose(fin);
    fclose(fout);
    return 0;
}