Cod sursa(job #2174173)

Utilizator AlexVulpoiuAlexandru Vulpoiu AlexVulpoiu Data 16 martie 2018 11:03:24
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.99 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int n,m,i,j,l,k,a[17],d[17][2001],c[65537][17];
bool viz[2001];
vector <pair <int,int> > v[2001];
queue <int> b;
int ok(int a,int b)
{
    return a&(1<<(b-1));
}
int main()
{
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d%d",&n,&m);
    scanf("%d",&k);
    for(i=1;i<=k;i++)
        scanf("%d",&a[i]);
    a[k+1]=1;
    while(m)
    {
        scanf("%d%d%d",&i,&j,&k);
        v[i].push_back(make_pair(j,k));
        v[j].push_back(make_pair(i,k));
        m--;
    }
    for(i=1;i<=k+1;i++)
    {
        b.push(a[i]);
        viz[a[i]]=1;
        while(!b.empty())
        {
            m=b.front();
            viz[m]=0;
            b.pop();
            for(j=0;j<v[m].size();j++)
                if(d[i][m]+v[m][j].second<d[i][v[m][j].first] || !d[i][v[m][j].first])
                {
                    d[i][v[m][j].first]=d[i][m]+v[m][j].second;
                    if(!viz[v[m][j].first])
                    {
                        viz[v[m][j].first]=1;
                        b.push(v[m][j].first);
                    }
                }
        }
    }
    if(!k)
        printf("%d\n",d[k+1][n]);
    else
    {
        m=1<<k;
        for(j=1;j<m;j++)
        {
            for(i=1;i<=k;i++)
                if(j==1<<(i-1))
                    break;
            if(i<=k)
            {
                c[j][i]=d[k+1][a[i]];
                continue;
            }
            for(i=1;i<=k;i++)
            {
                c[j][i]=2000000001;
                if(ok(j,i))
                    for(l=1;l<=k;l++)
                        if(i!=l && ok(j,l))
                            c[j][i]=min(c[j][i],c[j-(1<<(i-1))][l]+d[l][a[i]]);
            }
        }
        m=2000000001;
        for(i=1;i<=k;i++)
            m=min(m,c[(1<<k)-1][i]+d[i][n]);
        printf("%d\n",m);
    }
    return 0;
}