Cod sursa(job #2167667)

Utilizator zhm248Mustatea Radu zhm248 Data 13 martie 2018 22:47:30
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.12 kb
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
typedef pair<int,int>ii;
vector<ii>g[2001];
priority_queue<ii,vector<ii>,greater<ii> >pq;
int dist[2001],dd[32768][16],city[16],ddd[16][2001],put[16];
int main()
{
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    int n,m,i,x,y,z,j,k,l;
    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=k;++i)
    {
        scanf("%d",&city[i]);
    }
    for(i=1;i<=m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        g[x].push_back(ii(z,y));
        g[y].push_back(ii(z,x));
    }
    memset(dist,0x3f3f3f,sizeof(dist));
    dist[1]=0;
    pq.push(ii(0,1));
    while(!pq.empty())
    {
        int v=pq.top().second,dv=pq.top().first;
        pq.pop();
        if(dist[v]!=dv)
            continue;
        for(i=0;i<g[v].size();++i)
        {
            int vv=g[v][i].second;
            int dvv=g[v][i].first;
            if(dv+dvv<dist[vv])
            {
                dist[vv]=dv+dvv;
                pq.push(ii(dist[vv],vv));
            }
        }
    }
    if(!k)
        printf("%d\n",dist[n]);
    else
    {
        for(i=1;i<=k;++i)
        {
            memset(ddd[i],0x3f3f3f,sizeof(ddd[i]));
            ddd[i][city[i]]=0;
            pq.push(ii(0,city[i]));
            while(!pq.empty())
            {
                int v=pq.top().second,dv=pq.top().first;
                pq.pop();
                if(ddd[i][v]!=dv)
                    continue;
                for(j=0;j<g[v].size();++j)
                {
                    int vv=g[v][j].second;
                    int dvv=g[v][j].first;
                    if(dv+dvv<ddd[i][vv])
                    {
                        ddd[i][vv]=dv+dvv;
                        pq.push(ii(ddd[i][vv],vv));
                    }
                }
            }
        }
        int kk=1;
        for(i=0;i<k;++i)
        {
            put[i]=kk;
            kk*=2;
        }
        for(i=1;i<kk;++i)
        {
            bool ok=0;
            for(j=1;j<=k;++j)
            {
                if((1<<(j-1))==i)
                {
                    ok=1;
                    dd[i][j]=dist[city[j]];
                    break;
                }
            }
            if(!ok)
            {
                for(j=1;j<=k;++j)
                {
                    dd[i][j]=1000000000;
                    if(i&(1<<(j-1)))
                    {
                        for(l=1;l<=k;++l)
                        {
                            if(l!=j&&(i&(1<<(l-1))))
                            {
                                if(dd[i][j]>dd[i-(1<<(j-1))][l]+ddd[l][city[j]])
                                    dd[i][j]=dd[i-(1<<(j-1))][l]+ddd[l][city[j]];
                            }
                        }
                    }
                }
            }
        }
        int minim=1000000000;
        for(i=1;i<=k;++i)
        {
            if(dd[(1<<k)-1][i]+ddd[i][n]<minim)
                minim=dd[(1<<k)-1][i]+ddd[i][n];
        }
        printf("%d\n",minim);
    }
    return 0;
}