Cod sursa(job #918509)

Utilizator geniucosOncescu Costin geniucos Data 18 martie 2013 22:14:46
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.9 kb
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
int nr2,i1,nr,p,mini,x1,y1,c1,ul,i,j,k,n,m,v[20],d[20][20],ap[2003],b[2003],cd[2003],a[1<<15][17],heap[2003],poz[2003];
int min(int a,int b)
{
    if(a<b) return a;
    return b;
}
char a1[100];
vector < pair < int  , int > > vh[2009];
vector < pair < int  , int > >::iterator it;
int cmp(int p1,int p2)
{
    ///////1 dac p1<=p2
    if(b[heap[p1]]<=b[heap[p2]]) return 1;
    return 0;
}
void swap(int p1,int p2)
{
    int aux=heap[p1];
    poz[aux]=p2;
    poz[heap[p2]]=p1;
    heap[p1]=heap[p2];
    heap[p2]=aux;
}
void heapup(int p)
{
    if(p==1) return ;
    if(!cmp(p>>1,p))
    {
        swap(p>>1,p);
        heapup(p>>1);
    }
}
void heapdown(int p)
{
    int f;
    if((p<<1)>nr) return ;
    f=(p<<1);
    if(f+1<=nr&&cmp(f+1,f))
        f++;
    if(cmp(f,p))
    {
        swap(f,p);
        heapdown(f);
    }
}
int main()
{
freopen("ubuntzei.in","r",stdin);
freopen("ubuntzei.out","w",stdout);
scanf("%d",&n);
scanf("%d",&m);
scanf("%d",&k);
for(i=1;i<=k;i++)
    scanf("%d",&v[i]);
for(i1=1;i1<=m;i1++)
{
    scanf("%d",&x1);
    scanf("%d",&y1);
    scanf("%d",&c1);
    vh[x1].push_back(make_pair(y1,c1));
    vh[y1].push_back(make_pair(x1,c1));
}
v[0]=1;
for(i1=0;i1<=k;i1++)
{
    nr=0;
    for(i=1;i<=n;i++)
    if(i!=v[i1])
    {
        b[i]=cd[i]=10000000;
        nr++;
        heap[nr]=i;
        poz[i]=nr;
    }
    nr2=nr;
    ul=v[i1];
    b[ul]=cd[ul]=0;
    while(1)
    {
        for(it=vh[ul].begin();it!=vh[ul].end();it++)
            if(cd[ul]+it->second<cd[it->first])
            {
                if(b[it->first]==100000000)
                {
                    cd[it->first]=cd[ul]+it->second;
                    continue;
                }
                cd[it->first]=b[it->first]=cd[ul]+it->second;
                heapup(poz[it->first]);
            }
        if(nr2==0) break;
        ul=heap[1];
        b[ul]=100000000;
        nr2--;
        heapdown(1);
    }
    for(j=1;j<=k;j++)
        d[i1][j]=cd[v[j]];
    d[i1][k+1]=cd[n];
}
if(k==0)
{
    printf("%d\n",d[0][1]);
    return 0;
}
/*for(i=0;i<=k;i++)
{
    for(j=1;j<=k+1;j++)
        printf("%d ",d[i][j]);
    printf("\n");
}*/
//a[i][j]=configuratia i, ultima j
for(i=1;i<(1<<k);i++)
    for(j=0;j<k;j++)
        if(i&(1<<j))
            a[i][j+1]=99999999;
for(i=1;i<(1<<k);i++)
    for(j=0;j<k;j++)
        if(i&(1<<j))
        {
            if((i&(i-1))==0&&d[0][j+1]!=-1) a[i][j+1]=d[0][j+1];
            for(p=1;p<=k;p++)
                if((i&(1<<(p-1)))==0&&p!=j+1&&d[j+1][p]!=-1) a[i+(1<<(p-1))][p]=min(a[i+(1<<(p-1))][p],a[i][j+1]+d[j+1][p]);
        }
mini=99999999;
for(j=1;j<=k;j++)
    if(a[(1<<k)-1][j]+d[j][k+1]>0&&d[j][k+1]!=-1&&a[(1<<k)-1][j]+d[j][k+1]<mini)
        mini=a[(1<<k)-1][j]+d[j][k+1];
printf("%d\n",mini);
return 0;
}