Cod sursa(job #891980)

Utilizator NikitaUtiuNichita Utiu NikitaUtiu Data 25 februarie 2013 21:31:17
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <fstream>
#include <vector>
#include <list>
#include <queue>
#include <utility>
#include <functional>
#include <algorithm>
using namespace std;

#define INF 2000000000
typedef pair <int, int> pii;
typedef list <pii>::iterator l_it;

int n, m, k;
list <pii> muchii[10000];
priority_queue <pii, vector <pii>, greater <pii> > heap; // min priority_queue
int dist_ubu[16][16];
int dyn[16][1 << 16];

int dij_cost[20000];
void dijkstra(int source) {
    fill_n(dij_cost, n, INF);
    dij_cost[source] = 0; heap.push(make_pair(0, source));
    while(!heap.empty()) {
        int varf = heap.top().second; heap.pop();
        for(l_it it = muchii[varf].begin(); it != muchii[varf].end(); ++it)
            if(dij_cost[varf] + it->second < dij_cost[it->first]) {
                dij_cost[it->first] = dij_cost[varf] + it->second;
                heap.push(make_pair(dij_cost[it->first], it->first));
            }
    }
}

int main(void) {
    
    ifstream fin("ubuntzei.in");
    fin >> n >> m; int pozitii[16];
    fin >> k;
    for(int i = 0; i < k; ++i) {
        fin >> pozitii[i];
        --pozitii[i];
    }
    pozitii[k++] = n - 1;
    
    int start, dest, c;
    for(int i = 0; i < m; ++i) {
        fin >> start >> dest >> c;
        muchii[start-1].push_back(make_pair(dest-1, c));
        muchii[dest-1].push_back(make_pair(start-1, c));
    }
    fin.close();
    
    // precalculare distante
    for(int i = 0; i < k; ++i)
        fill_n(dyn[i], 1 << k, INF);
    
    for(int i = 0; i < k; ++i) {
        dijkstra(pozitii[i]);
        for(int j = 0; j < k; ++j)
            dist_ubu[i][j] = dij_cost[pozitii[j]];
    }
    dijkstra(0);
    for(int i = 0; i < k; ++i)
        dyn[i][1 << i] = dij_cost[pozitii[i]];
    
    for(int mask = 1; mask < (1 << k); ++mask) 
        for(int i = 0; i < k; ++i)
            if(mask & (1 << i)) 
                for(int bit = 0; bit < k; ++bit)
                    if(!((1 << bit) & mask))
                        dyn[bit][mask | (1 << bit)] 
                         = min(dyn[bit][mask | (1 << bit)], dyn[i][mask] + dist_ubu[i][bit]);
                                                          
    
    ofstream fout("ubuntzei.out");
    fout << dyn[k - 1][(1 << k) - 1];
    fout.close();
}