Cod sursa(job #2098320)

Utilizator DawlauAndrei Blahovici Dawlau Data 2 ianuarie 2018 17:39:41
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include<fstream>
#include<list>
#include<set>
#include<unordered_map>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
const int nrNodes = 2005 , bigValue = (1<<30), KMax = 20;

int nodes, edges, city[KMax], k, distances[nrNodes][nrNodes], chain[1<<KMax][KMax];
list< pair< int , int > > graph[nrNodes];

inline void read_data(){

    fin >> nodes >> edges;
    fin >> k;

    int i;
    for(i=0; i<k; ++i)
        fin >> city[i];

    int from, to, cst;
    while(edges--){
        fin >> from >> to >> cst;
        graph[from].push_back({to, cst});
        graph[to].push_back({from, cst});
    }
}

inline void dijkstra(int node, int distanceArray[]){

    int i;
    for(i = 1; i <= nodes; ++i)
        distanceArray[i] = bigValue;
    distanceArray[node] = 0;

    set< pair < int , int > > heap;
    heap.insert({0, node});
    list< pair < int , int > >::iterator it;

    while(!heap.empty()){
        node = heap.begin()->second;
        heap.erase(heap.begin());

        for(it = graph[node].begin(); it != graph[node].end(); ++it){
            int newNode = it->first;
            int newCost = it->second;

            if(distanceArray[newNode] > distanceArray[node] + newCost){
                if(distanceArray[newNode] != bigValue)
                    heap.erase(heap.find({distanceArray[newNode], newNode}));
                distanceArray[newNode] = distanceArray[node] + newCost;
                heap.insert({distanceArray[newNode], newNode});
            }
        }
    }
}

int getBestCost(){

    dijkstra(1, distances[1]);
    dijkstra(nodes, distances[nodes]);
    int i;
    for(i = 0; i < k; ++i)
        dijkstra(city[i], distances[city[i]]);

    if(k == 0)
        return distances[1][nodes];

    int mask, cityPos, endChain;
    for(mask = 0; mask < (1 << k); ++mask)
        for(cityPos = 0; cityPos < k; ++cityPos)
            chain[mask][cityPos] = bigValue;

    for(cityPos = 0; cityPos <k; ++cityPos)
        chain[(1 << cityPos)][cityPos] = distances[city[cityPos]][1];

    for(mask = 0; mask < (1 << k); ++mask)
        for(cityPos = 0; cityPos < k; ++cityPos)
            if(mask & (1 << cityPos))
                for(endChain = 0; endChain < k ; ++endChain)
                    if(endChain != cityPos)
                        if(mask & (1 << endChain))
                            chain[mask][cityPos] = min(chain[mask][cityPos], chain[mask ^ (1 << cityPos)][endChain] + distances[city[cityPos]][city[endChain]]);

    int BestCost = bigValue;
    for(cityPos = 0; cityPos < k; ++cityPos)
        BestCost = min(BestCost, chain[(1 << k) - 1][cityPos] + distances[city[cityPos]][nodes]);

    return BestCost;
}

int main(){
    read_data();
    fout << getBestCost();
}