Cod sursa(job #3004267)

Utilizator Botnaru_VictorBotnaru Victor Botnaru_Victor Data 16 martie 2023 11:00:52
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

struct muc{
    int n,c;
};


const int nmax=2002;
const int kmax=17;
const int maskmax=(1<<kmax);
const int imax=0x3f3f3f3f;

int admat[kmax][kmax];
//hamilton dinamica
int d[kmax][maskmax];


int prieten[nmax];
vector<muc> adj[nmax];
int n,m,k;

int dij[nmax];
void dodij(int st)
{
    for(int i=1;i<=n;i++) dij[i]=imax;
    dij[st]=0;

    priority_queue<pair<int,int>, vector<pair<int,int> >, greater<pair<int,int> > > q;

    q.push({0,st});

    while(!q.empty())
    {
        int cst=q.top().first,nod=q.top().second;
        q.pop();
        if(dij[nod]!=cst) continue;
        //cout<<"here "<<nod<<' '<<cst<<'\n';
        //cea mai importanta linie de cod
        if(prieten[nod]>0) admat[prieten[st]][prieten[nod]]=cst;
        for(auto e:adj[nod])
        {
            if(dij[e.n]>cst+e.c)
            {
                dij[e.n]=cst+e.c;
                q.push({dij[e.n],e.n});
            }
        }
    }

}


void doHamilton()
{
    const int kmask=(1<<k);
    for(int mask=0;mask<kmask;mask++)
    {
        for(int j=0;j<k;j++)
        {
            d[j][mask]=imax;
        }
    }
    d[0][1]=0;

    for(int mask=0;mask<kmask;mask++)
    {
        for(int dr=0;dr<k;dr++)
        {
            if(!(mask&(1<<dr))) continue;

            int stmask=mask-(1<<dr);

            for(int st=0;st<k;st++)
            {
                if(!(stmask&(1<<st))) continue;
                if(admat[st][dr]==0) continue;
                d[dr][mask]=min(d[dr][mask],d[st][stmask]+admat[st][dr]);
            }

            //cout<<"here "<<mask<<' '<<stmask<<' '<<dr<<','<<d[dr][mask]<<'\n';
        }
    }
}

int main()
{
    f>>n>>m>>k;
    int a,b,c;

    for(int i=1;i<=k;i++)
    {
        f>>a;
        prieten[a]=i;
    }
    k++;
    prieten[n]=k;
    k++;

    for(int i=1;i<=m;i++)
    {
        f>>a>>b>>c;
        adj[a].push_back({b,c});
        adj[b].push_back({a,c});
    }

    dodij(1);

    for(int i=2;i<=n;i++)
    {
        if(prieten[i]>0) dodij(i);
    }

    doHamilton();

    g<<d[k-1][(1<<k)-1]<<'\n';


    return 0;
}