Cod sursa(job #2130654)

Utilizator pslaPislariu Alexandru psla Data 13 februarie 2018 20:03:19
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <fstream>
#define Nmax 2001
#define Kmax 15
#define INF 1000000000
using namespace std;
int costuri[Nmax][Nmax];
int distances[Nmax][Nmax];
void initializareMat(int N)
{
    for(int i=1;i<N;i++)
        for(int j=i+1;j<=N;j++)
        {
            costuri[i][j]=INF;
            costuri[j][i]=INF;
        }
}
void read(int &N,int &M,int &K,int v[])
{
    ifstream in("ubuntzei.in");
    in>>N>>M;
    in>>K;
    for(int i=0;i<K;i++)
        in>>v[i];
//initializam matricea costurilor
    initializareMat(N);
//construim matricea costurilor
    int c1,c2,cost;
    for(int i=0;i<M;i++)
    {
        in>>c1>>c2>>cost;
        costuri[c1][c2]=cost;
        costuri[c2][c1]=cost;
    }
    in.close();
}
void initializer(int N,bool viz[],int nod)
{
    for(int i=1;i<=N;i++)
    {
        viz[i]=0;
        distances[nod][i]=costuri[nod][i];
    }
}
void Dijkstra(int N,int nod)
{//initializam vectorii
    bool vizitat[Nmax];
    initializer(N,vizitat,nod);
//punem nodul
    vizitat[nod]=1;
    distances[nod][nod]=0;
//pornim cautarea distantelor
    bool gasit=0;
    int pozNou,min;
    while(!gasit)
    {
        min=INF;
        for(int i=1;i<=N;i++)
            if(!vizitat[i] and distances[nod][i]<min)
            {
                min=distances[nod][i];
                pozNou=i;
            }
        if(min!=INF)
        {
            vizitat[pozNou]=1;
        //actualizam distantele
            for(int i=1;i<=N;i++)
                if(distances[nod][i]>min+costuri[pozNou][i])
                    distances[nod][i]=min+costuri[pozNou][i];
        }
        else gasit=1;
    }
}
int Lmin=INF,L=0;
bool viz[Nmax];
int st[Kmax];
void BKT(int N,int K,int v[],int pas)
{
    for(int i=0;i<K;i++)
    {
        st[pas]=i;
        if(!viz[v[st[pas]]])
        {
            viz[v[st[pas]]]=1;
            if(pas>0)L+=distances[v[st[pas-1]]][v[st[pas]]];
            else L=distances[1][v[st[pas]]];
            if(L<Lmin)
            {
                if(pas==K-1)
                {
                    L=L+distances[v[st[pas]]][N];
                    if(L<Lmin)Lmin=L;
                }
                else BKT(N,K,v,pas+1);
            }
            viz[v[st[pas]]]=0;
            L-=distances[v[st[pas-1]]][v[st[pas]]];
        }
    }
}
int getMinim(int N,int K,int v[])
{//adaugam distantele fata de nodul 1
    Dijkstra(N,1);
    if(K==0)return distances[1][N];
//calculam distantele pentru fiecare prieten
    for(int i=0;i<K;i++)
        Dijkstra(N,v[i]);
    BKT(N,K,v,0);
    return Lmin;
}
int main()
{   int N,M;
    int K,prieteni[Kmax];
    read(N,M,K,prieteni);
    ofstream out("ubuntzei.out");
    out<<getMinim(N,K,prieteni);
    out.close();
    return 0;
}