Cod sursa(job #1502546)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 14 octombrie 2015 19:43:52
Problema Gather Scor 90
Compilator c Status done
Runda Arhiva de probleme Marime 3.91 kb
#include <stdio.h>
#include <stdlib.h>
#define MAXN 750
#define MAXK 15
#define MAXM 1250
#define INF 1000000000000000LL
int hot[MAXK],celula[2*MAXM+1],ind[MAXN+1],next[2*MAXM+1],ldrum[2*MAXM+1],capdrum[2*MAXM+1],vfhot[MAXN+1],con=1;
int celulaH[MAXM],vfcelH[MAXN];
long long distanta[MAXK][MAXK][MAXK],A[MAXK][1<<(MAXK)],H[MAXM+1];
inline void add(int a,int b,int c,int d){
    celula[con]=a;
    next[con]=ind[b];
    ind[b]=con;
    ldrum[con]=c;
    capdrum[con]=d;
    con++;
}
inline void dijkstra(int nod,int cap,int n){
    int conH=1,poz,i,nrnod=1;
    long long s;
    poz=ind[hot[nod]];
    vfcelH[hot[nod]]=1;
    while(poz){
        if(capdrum[poz]>=cap){
            H[conH]=ldrum[poz];
            celulaH[conH]=celula[poz];
            urcare(conH);
            conH++;
        }
        poz=next[poz];
    }
    while(conH>0){
        if(vfhot[celulaH[1]]&&H[1]<distanta[nod][vfhot[celulaH[1]]-1][cap])
            distanta[nod][vfhot[celulaH[1]]-1][cap]=H[1];
        if(celulaH[1]==1&&H[1]<distanta[nod][nod][cap])
            distanta[nod][nod][cap]=H[1];
        vfcelH[celulaH[1]]=1;
        poz=ind[celulaH[1]];
        s=H[1];
        conH--;
        H[1]=H[conH];
        celulaH[1]=celulaH[conH];
        coborare(1,conH);
        while(poz){
            if(capdrum[poz]>=cap&&vfcelH[celula[poz]]==0){
                H[conH]=ldrum[poz]+s;
                celulaH[conH]=celula[poz];
                urcare(conH);
                conH++;
            }
            poz=next[poz];
        }
        nrnod++;
    }
    for(i=1;i<=n;i++)
        vfcelH[i]=0;
}
inline void swap(int x,int y){
    long long aux=H[x];
    H[x]=H[y];
    H[y]=aux;
    int aux1=celulaH[x];
    celulaH[x]=celulaH[y];
    celulaH[y]=aux1;
}
inline int t_nod(int nod){
    return nod/2;
}
inline int l_nod(int nod){
    return 2*nod;
}
inline int r_nod(int nod){
    return 2*nod+1;
}
inline void urcare(int nod){
    while(t_nod(nod)&&H[t_nod(nod)]>H[nod]){
        swap(nod,t_nod(nod));
        nod=t_nod(nod);
    }
}
inline void coborare(int nod,int n){
    int flag=1;
    while(l_nod(nod)<n&&flag){
        flag=nod;
        if(H[l_nod(nod)]<H[nod]&&(H[r_nod(nod)]>H[l_nod(nod)]||r_nod(nod)>=n))
               flag=l_nod(nod);
        else
           if(r_nod(nod)<n&&H[r_nod(nod)]<H[nod])
                flag=r_nod(nod);
        if(nod==flag)
             flag=0;
        else{
            swap(nod,flag);
            nod=flag;
        }
    }
}
int main(){
    FILE*fi,*fout;
    int i,j,n,m,k,a,b,c,d,x,nr,priz,z;
    long long min;
    fi=fopen("gather.in" ,"r");
    fout=fopen("gather.out" ,"w");
    fscanf(fi,"%d%d%d" ,&k,&n,&m);
    for(i=0;i<k;i++){
        fscanf(fi,"%d" ,&hot[i]);
        vfhot[hot[i]]=i+1;
    }
    for(i=0;i<m;i++){
        fscanf(fi,"%d%d%d%d" ,&a,&b,&c,&d);
        add(a,b,c,d);
        add(b,a,c,d);
    }
    for(i=0;i<k;i++)
        for(j=0;j<k;j++)
           for(z=0;z<k;z++)
               distanta[i][j][z]=INF;
    for(i=0;i<k;i++)
       for(j=0;j<k;j++)
            dijkstra(i,j,n);
    for(i=0;i<k;i++)
        for(j=0;j<(1<<k);j++)
           A[i][j]=INF;
    for(i=0;i<k;i++)
        A[i][(1<<i)]=distanta[i][i][0];
    for(j=0;j<(1<<k);j++)
       for(i=0;i<k;i++)
            if((j&(1<<i))>0&&((1<<i)!=j)){
               nr=j;
               priz=0;
               while(nr){
                   priz+=(nr&1);
                   nr>>=1;
               }
               for(x=0;x<k;x++)
                   if(A[x][j^(1<<i)]<INF&&distanta[x][i][priz-1]<INF&&i!=x&&((j&(1<<x))>0)&&A[i][j]>A[x][j^(1<<i)]+priz*distanta[x][i][priz-1])
                      A[i][j]=A[x][j^(1<<i)]+priz*distanta[x][i][priz-1];
            }
    min=INF;
    for(i=0;i<k;i++)
        if(min>A[i][(1<<k)-1])
           min=A[i][(1<<k)-1];
    fprintf(fout,"%lld" ,min);
    fclose(fi);
    fclose(fout);
    return 0;
}