Cod sursa(job #2676442)

Utilizator PopescuAndreiAlexandruPopescu Andrei Alexandru PopescuAndreiAlexandru Data 24 noiembrie 2020 11:51:12
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

const int INF = (1<<30);
const int DIM = 2005;
const int KMAX = 17;

int n,m,k,x,y,c,C[DIM],DP[DIM][DIM],Sol[(1<<KMAX)][KMAX];

bool InQueue[DIM];

vector < pair<int,int> > G[DIM];

struct Compare
{
    bool operator()(pair<int,int> a, pair<int,int> b)
        {
            return (DP[a.first][a.second]>DP[b.first][b.second]);
        }
};

void Read()
{
    fin>>n>>m>>k;
    for(int i=1;i<=k;i++)
        fin>>C[i];
    while(m--)
        {
            fin>>x>>y>>c;
            G[x].push_back(make_pair(y,c));
            G[y].push_back(make_pair(x,c));
        }
    C[k+1]=n;C[0]=1;
}

priority_queue < pair<int,int> , vector< pair<int,int> >, Compare > Q;

void FindPath(int CrtNode)
{
    Q.push(make_pair(CrtNode,CrtNode));
    while(!Q.empty())
        {
            int node=Q.top().second;
            InQueue[node]=0;
            Q.pop();
            vector < pair<int,int> > ::iterator it;
            for(it=G[node].begin();it!=G[node].end();it++)
                {
                    int next=(*it).first;
                    int edge=(*it).second;
                    if(DP[CrtNode][node]+edge<DP[CrtNode][next])
                        {
                            DP[CrtNode][next]=DP[CrtNode][node]+edge;
                            if(!InQueue[next])
                                {
                                    InQueue[next]=1;
                                    Q.push(make_pair(CrtNode,next));
                                }
                        }
                }
        }
}

void Dijkstra()
{
    for(int i=0;i<=k;i++)
            for(int j=1;j<=n;j++)
                DP[C[i]][j]=INF;
    for(int i=0;i<=k;i++)
        {
            DP[C[i]][C[i]]=0;
            FindPath(C[i]);
        }
}

void SetArray()
{
    for(int mask=0;mask<(1<<(k+2));mask++)
        for(int i=0;i<=k+1;i++)
            Sol[mask][i]=INF;
}

void Bitmask()
{
    Sol[1][0]=0;
    for(int mask=1;mask<(1<<(k+2));mask++)
        {
            for(int i=1;i<=k+1;i++)
                {
                    if(mask & (1<<i))
                        {
                            for(int j=0;j<=k;j++)
                                {
                                    if(i!=j && (mask & (1<<j)))
                                        Sol[mask][i]=min(Sol[mask][i],Sol[mask^(1<<i)][j]+DP[C[j]][C[i]]);
                                }
                        }
                }

        }
    fout<<Sol[(1<<(k+2))-1][k+1]<<'\n';
}

int main()
{
    Read();
    Dijkstra();
    SetArray();
    Bitmask();
}