Cod sursa(job #1640973)

Utilizator iulian_f2kGuraliuc Iulian iulian_f2k Data 8 martie 2016 20:10:55
Problema Ubuntzei Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.23 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <utility>
#include <queue>
#define INF ( (1 << 30) - 1)
#define NMAX 2005
using namespace std;

vector < pair < int, int> > G[NMAX];                                //Graful memorat prin liste de adiacenta. second = costul
vector<int> k;                                                       //Vectorul ce contine toti ubuntzeii, + nodul 1 si nodul N
vector<int> dist[20];                                               //Vectorul cu distante. Se va calcula doar pentru nodul 1 si ubuntzei
int N, M, K, dTotala;                                                        //nodurile din configuratie
vector<bool> viz;

void initializare();
void bellmanFord(int iNodStart);
int memoizare(int nod, int conf);
void rezolva(int iNod, int prec);

int main()
{
    initializare();
    for(int i=0; i<k.size()-1; ++i)                                 //BellmanFord-ul se face pentru toate nodurile din vector, exceptie nodul N
        bellmanFord(i);
    viz.assign(K+3, 0);
    rezolva(0, 0);
    return 0;                                                       //nodul N si contine toate elementele din vectorul cu ubuntzei.
}

void rezolva(int iNod, int prec)
{
    if(iNod == K)
        cout<<dTotala + dist[prec][N]<<'\n';
    else
    {
        int ubMin, dmin = INF;
        if(iNod == 0){
            for(int i=1; i<=K; i++)
                if(viz[i] == 0)
                    if(dmin > dist[0][k[i]] && dist[0][k[i]] != 0) {
                        dmin = dist[0][k[i]];
                        ubMin = i;
                    }
            dTotala += dmin;
            viz[ubMin] = true;
            rezolva(iNod+1, ubMin);
        }
        else {
            for(int i=1; i<=K; i++)
                if(viz[i] == 0)
                    if(dmin > dist[prec][k[i]] && dist[prec][k[i]] != 0) {
                        dmin = dist[prec][k[i]];
                        ubMin = i;
                    }
            dTotala += dmin;
            viz[ubMin] = true;
            rezolva(iNod+1, ubMin);
        }
    }
}

void bellmanFord(int iNodStart)
{
    int nod, vec, d, dvec;
    int nodStart = k[iNodStart];
    queue<int>Q;
    vector<bool>inQueue;
    inQueue.assign(N+2, 0);
    dist[iNodStart].assign(N+2, INF);
    dist[iNodStart][nodStart] = 0;
    Q.push(nodStart);
    while(!Q.empty())
    {
        nod = Q.front();
        Q.pop();
        d = dist[iNodStart][nod];
        for(int i=0; i<G[nod].size(); ++i)
        {
            vec = G[nod][i].first;
            dvec = G[nod][i].second;
            if(d + dvec < dist[iNodStart][vec]) {
                dist[iNodStart][vec] = d + dvec;
                if(!inQueue[vec])
                    Q.push(vec);
            }
        }
    }
}
void initializare()
{
    freopen("ubuntzei.in", "rt", stdin);
    freopen("ubuntzei.out", "wt", stdout);
    int ubu, x, y, c;
    scanf("%d%d%d", &N, &M, &K);
    k.push_back(1);
    for(int i=1; i<=K; ++i) {
        scanf("%d", &ubu);
        k.push_back(ubu);
    }
    k.push_back(N);
    for(int i=1; i<=M; ++i) {
        scanf("%d%d%d", &x, &y, &c);
        G[x].push_back(make_pair(y, c));
        G[y].push_back(make_pair(x, c));
    }
}