Cod sursa(job #477664)

Utilizator coditzaDiana Kelerman coditza Data 15 august 2010 20:55:43
Problema Algoritmul lui Dijkstra Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.88 kb
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <deque>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <iterator>
 
using namespace std;

template<typename T>
void printV(const vector<T> &v) {
    for (size_t i = 0; i < v.size(); ++i) {
        cout << v[i] << " ";
    }
    cout << endl;
}

class dijkstra {
private:
    typedef vector<int> VI;
    typedef vector<int>::iterator VIIt;

    typedef pair<int, int> Edge;

    typedef map<Edge, int> CostFunc;

    typedef vector<VI> Graf;

    static const int INF = ~(1 << 31);

    Graf g;
    CostFunc w;

    class Hash {
    public:
        Hash(int n, int k) : hash(), key(n, k) {
            for (size_t i = 0; i < key.size(); ++i) {
                hash.insert(Node(k, i));
            }
        }

        pair<int, int> extractMinimum() {
            Node n = *hash.begin();
            hash.erase(hash.begin());

            return n;
        }
/*
        void insertNode(int v, int d) {
            insertKey(v, d);
            hash.insert(Node(d, v));
        }
*/
        void updateNode(int v, int d) {
            HashSetIt it = hash.find(Node(key[v], v));

            if (it != hash.end()) {
                hash.erase(it);
            }
            key[v] = d;
            hash.insert(Node(d, v));
        }

        int getKey(int v) {
            return key[v];
        }

        vector<int> getKeys() {
            return key;
        }

        bool empty() {
            return hash.empty();
        }
    private:
        typedef pair<int, int> Node;
        typedef set<Node> HashSet;
        typedef HashSet::iterator HashSetIt;

        HashSet hash;
        VI key;

        /*
        void insertKey(int v, int d) {
            if (v >= (int)key.size()) {
                key.resize(v + 1);
            }
            key[v] = d;
        }
        */
    };

    void buildGraph(ifstream &in) {
        int n, m;
        in >> n >> m;

        Graf(n, VI()).swap(g);

        for (int i = 0; i < m; ++i) {
            int x, y, c;
            in >> x >> y >> c;

            if (x == y) {
                continue;
            }

            g[x - 1].push_back(y - 1);
            w.insert(pair<Edge, int>(Edge(x - 1, y - 1), c));
            w.insert(pair<Edge, int>(Edge(y - 1, x - 1), c));
        }
    }

public:
    void func_dijkstra(ifstream &in, ofstream &out) {

        buildGraph(in);

        /*
        for (size_t i = 0; i < g.size(); ++i) {
            cout << i << ": ";
            printV<int>(g[i]);
        }
        */

        Hash h(g.size(), INF);
        h.updateNode(0, 0);

        VI p(g.size(), -1);
        VI vis(g.size(), 0);
        p[0] = -1;

        while (!h.empty()) {
            pair<int, int> node = h.extractMinimum();

            int u = node.second;
            int d = node.first;

            vis[u] = 1;

  //          cout << "--> " << u << " " << d << endl;

//            cout << "relaxing: ";
            for (size_t i = 0; i < g[u].size(); ++i) {
                int v = g[u][i];

                if (vis[v] == 0) {

                    int r;
                    if (d == INF) {
                        r = INF;
                    } else {
                        r = d + w[Edge(u, v)];
                    }
                    if (h.getKey(v) > r) {
      //                  cout << v << " ";
                        h.updateNode(v, r);
                        p[v] = u;
                    }
                }
            }
    //        cout << endl;
        }

        VI d = h.getKeys();

        for (size_t i = 1; i < d.size(); ++i) {
            if (d[i] == INF) {
                d[i] = 0;
            }
        }
        copy(d.begin() + 1, d.end(), ostream_iterator<int>(out, " "));
    }
};

int main() {
    ifstream in("dijkstra.in");
    ofstream out("dijkstra.out");

    dijkstra x; x.func_dijkstra(in, out);
}