Cod sursa(job #2149126)

Utilizator RaduMirceaAndreiRadu Mircea Andrei RaduMirceaAndrei Data 2 martie 2018 12:29:50
Problema Ubuntzei Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.95 kb
# include <fstream>
# include <vector>
# define DIM 2005
# define INF 0x3f3f3f3f
# define f first
# define s second
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
vector<int> Lista[DIM];
pair<int,int> h[4*DIM];
int b[DIM][DIM],a[DIM][DIM],d[15][(1<<15)];
int rv[(1<<15)],v[DIM],f[DIM],poz[DIM];
int n,m,nr,x,y,cost,i,j,k,sol,nh;
void add(pair<int,int> val){
    h[++nh]=val;
    int c=nh,p=c/2;
    while(p!=0){
        if(h[c].f<h[p].f){
            swap(h[c],h[p]);
            c=p;
            p/=2;
        }
        else
            break;
    }
}
void change(int pl,int val){
    h[pl].f=val;
    int c=pl,p=c/2;
    while(p!=0){
        if(h[c].f<h[p].f){
            swap(h[c],h[p]);
            poz[h[c].s]=c;
            poz[h[p].s]=p;
            c=p;
            p/=2;
        }
        else
            break;
    }
}
void off(){
    h[1]=h[nh--];
    int p=1,c=2;
    while(c<=nh){
        if(h[c].f>h[c+1].f&&c<nh)
            c++;
        if(h[c].f<h[p].f){
            swap(h[c],h[p]);
            poz[h[c].s]=c;
            poz[h[p].s]=p;
            p=c;
            c*=2;
        }
        else
            break;
    }
}
int main () {
    fin>>n>>m>>nr;
    v[0]=1;
    for(i=1;i<=nr;i++)
        fin>>v[i];
    for(i=1;i<=m;i++){
        fin>>x>>y>>cost;
        Lista[x].push_back(y);
        Lista[y].push_back(x);
        b[x][y]=b[y][x]=cost;
    }
    for(k=1;k<=n;k++){
        add(make_pair(0,k));
        f[k]=0;
        for(i=k+1;i<=n;i++){
            f[i]=INF;
            add(make_pair(INF,i));
        }
        for(i=1;i<k;i++){
            f[i]=b[k][i];
            add(make_pair(f[i],i));
        }
        for(i=1;i<=n;i++)
            poz[h[i].s]=i;
        while(nh){
            int nc=h[1].s;
            if(f[nc]<h[1].f){
                off();
                continue;
            }
            off();
            for(int i=0;i<Lista[nc].size();i++){
                int nv=Lista[nc][i];
                if(f[nv]>f[nc]+b[nc][nv]){
                    f[nv]=f[nc]+b[nc][nv];
                    change(poz[nv],f[nv]);
                }
            }
        }
        for(i=1;i<=n;i++)
            b[k][i]=b[i][k]=f[i];
    }
    for(i=1;i<(1<<nr);i++){
        for(j=0;j<nr;j++)
            d[j][i]=INF;
    }
    for(i=1,j=0;j<nr;i*=2,j++){
        rv[i]=j;
        d[j][i]=b[1][v[j+1]];
    }
    for(i=1;i<(1<<nr);i++){
        for(j=i;j>0;j-=(j&(-j))){
            x=rv[(j&(-j))];
            if(d[x][i]==INF)
                continue;
            for(k=(i^((1<<nr)-1));k>0;k-=(k&(-k))){
                y=rv[(k&(-k))];
                d[y][i+(k&(-k))]=min(d[y][i+(k&(-k))],d[x][i]+b[v[x+1]][v[y+1]]);
            }
        }
    }
    sol=INF;
    for(i=1;i<=nr;i++)
        sol=min(sol,d[i-1][(1<<nr)-1]+b[v[i]][n]);
    if(nr==0)
        fout<<b[1][n]<<"\n";
    else
        fout<<sol<<"\n";
    return 0;
}