Cod sursa(job #1824335)

Utilizator Emil64Emil Centiu Emil64 Data 7 decembrie 2016 18:58:18
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.83 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <cassert>
#include <queue>
#include <vector>
#include <utility>
#include <algorithm>

using namespace std;


const int INF = 0x3f3f3f3f;


vector< pair<int,int> > g[2001];
int n, m, k;
int d[1<<15][20], dist[20][2001], ubuntzei[20], u[2001];


void dijkstra(int start, int d[]) {
    priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > heap;
    pair<int, int> top;
    int k;

    // D = dist[start];
    memset(u, 0, sizeof(u));
    for (int i = 1; i <= n; i++) d[i] = INF;

    d[start] = 0;
    heap.push( make_pair(0, start) );

    for (int i = 0; i < n - 1; i++) {
        do {
            top = heap.top();
            k = top.second;
            heap.pop();
        } while (u[k]);

        u[k] = 1;
        for(std::vector<pair<int, int> >::iterator it = g[k].begin(); it != g[k].end(); ++it)
            if (!u[it->first]) {
                d[it->first] = min(d[it->first], d[k] + it->second);
                heap.push( make_pair(d[it->first], it->first) );
            }
    }

}

int solve() {
    if (k == 0) {
        dijkstra(1, dist[0]);
        return dist[0][n];
    }

    for (int i = 0; i < k; i++)
        dijkstra(ubuntzei[i], dist[i]);

    int c, best;


    d[0][0] = 0;
    for (int conf = 1; conf < (1 << k); conf++) {

        for (int i = 0; i < k; i++)
            if (conf & (1 << i)) {

                c = conf ^ (1 << i);
                if (c) {
                    best = INF;
                    for (int j = 0; j < k; j++)
                        if (c & (1 << j))
                            best = min(best, d[c][j] + dist[i][ ubuntzei[j] ]);
                    d[conf][i] = best;
                } else {
                    d[conf][i] = dist[i][1];
                }
            }

    }

    best = INF;
    c = (1 << k) - 1;
    for (int i = 0; i < k; i++)
        if (c & (1 << i))
            best = min(best, d[c][i] + dist[i][n]);

    return best;
}

int main() {
    ifstream f("ubuntzei.in");
    ofstream _g("ubuntzei.out");
    f >> n >> m;
    f >> k;
    for(int i=0; i<k; i++)
        f >> ubuntzei[i];
    int x, y, c;
    for(int i=0; i<m; i++){
        f >> x >> y >> c;
        g[x].push_back( make_pair(y, c) );
        g[y].push_back( make_pair(x, c) );
    }
    _g << solve() << "\n";

    return 0;
}


/*
#include <iostream>
#include <fstream>
#include <string.h>
#include <utility>
#include <queue>
#include <vector>

using namespace std;

const int INF = 0x3f3f3f3f;

struct nod{
    int a, b;
}o;
vector<nod> g[2001];
int n, m;
int d[1<<15][20], dist[20][2001], ubuntzei[20], u[2001];

struct pq
{
    nod valoare;
    bool operator<(const pq &x)  const
    {
        return valoare.b > x.valoare.b;
    }
};

void dijkstra(int start, int d[]){

    priority_queue <pq> heap;
    nod top;
    pq aux;
    int k;
    for(int i=0; i<=n; i++)
        u[i] = 0;
    for(int i=0; i<=n; i++)
        d[i] = INF;

    d[start] = 0;
    o.a = 0;
    o.b = start;
    aux.valoare = o;
    heap.push(aux);

    for(int i=0; i<n-1; i++){

        aux = heap.top();
        top = aux.valoare;
        k = top.b;
        heap.pop();
        while (u[k]){
            aux = heap.top();
            top = aux.valoare;
            k = top.b;
            heap.pop();
        }

        u[k] = 1;
        for(std::vector<nod>::iterator it = g[k].begin(); it != g[k].end(); ++it)
            if(!u[it->a]){
                d[it->a] = min(d[it->a], d[k] + it->b);
                aux.valoare.a = d[it->a];
                aux.valoare.b = it->a;
                heap.push(aux);
            }
    }

}


int main() {

     ifstream f("ubuntzei.in");
    ofstream _g("ubuntzei.out");
    int k;
    f >> n >> m;
    f >> k;
    for(int i=0; i<k; i++)
        f >> ubuntzei[i];
    int x, y, c;
    for(int i=0; i<m; i++){
        f >> x >> y >> c;
        o.a = y;
        o.b = c;
        g[x].push_back(o);
        o.a = x;
        g[y].push_back(o);
    }

    if(k == 0){
        dijkstra(1, dist[0]);
        _g << dist[0][n] <<"\n";
        return 0;
    }

    for(int i=0; i<k; i++)
        dijkstra(ubuntzei[i], dist[i]);

    int best;
    d[0][0] = 0;

    for(int cfg=1; cfg < (1<<k); cfg++){
        for(int i=0; i<k; i++)
            if(cfg & (1 << i)){
                c = cfg ^ (1 << i);
                if(c){
                    best = INF;
                    for(int j=0; j<k; j++)
                        if(c & (1 << j))
                            best = min(best, d[c][j] + dist[i][ubuntzei[j]]);
                    d[cfg][i] = best;
                }
                else{
                    d[cfg][i] = dist[i][1];
                }
            }
    }

    best = INF;
    c = (1 << k) - 1;
    for(int i = 0; i < k; i++)
        if(c & (1 << i))
            best = min(best, d[c][i] + dist[i][n]);

    _g << best << "\n";
    _g.close();
    return 0;

}
*/