Cod sursa(job #2429858)

Utilizator AndreiDeltaBalanici Andrei Daniel AndreiDelta Data 11 iunie 2019 16:10:00
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <bits/stdc++.h>
#define Dim 2007
#define Max 32800
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
int N,M,K,Town[Dim],T[Dim][Max],dp[Dim][Dim];
int os,a,b,c,ans;
bool viz[Dim][Dim],city[Dim];
typedef pair<int,int> pii;

struct cmp
{
    bool operator()(int X,int Y)
    {
        if(dp[os][X]>dp[os][Y]) return 1;
        else return 0;
    }
};

vector <pii> V[Dim];
priority_queue < int,vector<int>,cmp > minheap;


void Solve()
{
    viz[os][os]=1;
    dp[os][os]=0;
    minheap.push(os);
    while(!minheap.empty())
    {
        int nod=minheap.top();
        minheap.pop();
        viz[os][nod]=0;

        for(unsigned int i=0;i<V[nod].size();i++)
        {
            int vecin=V[nod][i].first;
            int cost=V[nod][i].second;

            if(dp[os][nod]+cost<dp[os][vecin])
            {
                dp[os][vecin]=dp[os][nod]+cost;
                if(!viz[os][vecin])
                {
                    viz[os][vecin]=1;
                    minheap.push(vecin);
                }
            }
        }
    }
}

int main()
{
    f>>N>>M>>K;
    for(int i=0;i<K;i++)
    {
        f>>Town[i];
        city[Town[i]]=1;
    }
    for(int i=1;i<=M;i++)
    {
       f>>a>>b>>c;
       V[a].push_back({b,c});
       V[b].push_back({a,c});
    }
    for(int i=1;i<=N;i++)
    for(int j=1;j<=N;j++)
    dp[i][j]=INT_MAX;

    os=1;
    Solve();

    for(int i=0;i<K;i++)
    {
       os=Town[i];
       Solve();
    }

    for(int i=0;i<K;i++)
    for(int j=1;j<(1<<K);j++) T[Town[i]][j]=INT_MAX;

    for(int i=0;i<K;i++)
    T[Town[i]][(1<<i)]=dp[1][Town[i]];

    for(int i=1;i<=N;i++)
    if(!city[i])
    T[i][0]=dp[1][i];

    for(int i=1;i<(1<<K);i++)
       for(int j=0;j<K;j++)
    if( ( i&(1<<j) )>0 )
          for(int l=0;l<K;l++)
    if(  ( i&(1<<l) )>0  )
    T[Town[j]][i]=min(T[Town[j]][i],T[Town[l]][i-(1<<j)]+dp[Town[l]][Town[j]]);

    ans=INT_MAX;
    for(int i=0;i<K;i++) ans=min(ans,T[Town[i]][(1<<K)-1]+dp[Town[i]][N]);

    if(K==0) g<<dp[1][N];
    else
    g<<ans;


    return 0;
}