Cod sursa(job #1548187)

Utilizator iulian_f2kGuraliuc Iulian iulian_f2k Data 10 decembrie 2015 17:22:24
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#define nmax 2005
#define Inf ((1<<30)+10)
using namespace std;

vector<bool> inQueue;
vector< pair<int,int > >v[nmax];
vector<int> m[20];
vector<int> kn;
int n,nrmuchii,k;
int mp[17][(1<<15)];

void citire()
{
    int a,b,c;
    scanf("%d %d\n%d",&n,&nrmuchii,&k);
    for(int i=1; i<=k; i++)
    {
        scanf("%d",&c);
        kn.push_back(c);
    }

    for(int i=1; i<= nrmuchii; i++)
    {
        scanf("%d %d %d",&a,&b,&c);
        v[a].push_back(make_pair(b,c));//in v[a] adaug vecinul b cu costul muchiei (ab) =c;
        v[b].push_back(make_pair(a,c));//in v[a] adaug vecinul b cu costul muchiei (ab) =c;
    }
}

int last = 0;
void bellmanFord(int first)
{
//    m.push_back(*(new vector<int>()));
//    last = m.size () - 1;

    m[last].assign(n+1,Inf);


    queue<int> C;
    int p;
    inQueue.assign(n+1,0);//marcheaza daca nodul a intrat deja in coada
    m[last][first] = 0;
    C.push(first);
    inQueue[first]=true;
    while(!C.empty())
    {
        p=C.front();
        C.pop();
        inQueue[p]=false;

        for(int i=0; i<v[p].size(); i++)//pentru toti vecinii lui p
        {
            int vecin=v[p][i].first;
            int cost=v[p][i].second;
            if(m[last][p]+cost < m[last][vecin])//daca distanta prin nodul p este mai mica
            {
                m[last][vecin]=m[last][p]+cost;
                if( !inQueue[vecin])//daca vecinul nu a intrat in coada
                {
                    C.push(vecin);//se adauga
                    inQueue[vecin]=true;//se marcheaza adaugarea
                }
            }
        }

    }

    last++;
}
int optimize(int last, int sequence);
int main()
{
    freopen("ubuntzei.in","rt",stdin);
    freopen("ubuntzei.out","wt",stdout);

    kn.push_back (1);
    citire();

    for(int i=0; i<=k; i++)
        bellmanFord(kn[i]);
    kn.push_back(n);

    for(int i=0;i<=k+1;i++)
        for(int j=0;j<(1<<k);j++)
            mp[i][j]=Inf;

    cout<< optimize(kn.size()-1,(1<<k)-1);
    return 0;
}

int optimize(int last, int sequence)
{
    if(sequence==0)
        return m[0][kn[last]];
    if(mp[last][sequence]<Inf)
        return mp[last][sequence];

    for(int i=1; i<=k; i++)
    {
        int rez=Inf;
        if((sequence>>(i-1)) & 1 ) {
            rez=optimize(i,sequence-(1<<(i-1)));
            int arc = m[i][kn[last]];
            rez += arc;
        }
        if(rez<mp[last][sequence])
            mp[last][sequence]=rez;
    }

    return mp[last][sequence];
}