/*
 * graph.cc
 */

#include <iostream>

using namespace std;

template <class T>
class Graph {
    T * graph;
    int size;
    T infinity;
public:
    Graph(int n, T inf_cost);
    ~Graph();
    void link(int n1, int n2, T cost);
    void unlink(int n1, int n2);
    bool linked(int n1, int n2);
    template <class T1> friend ostream& operator<<(ostream &out, Graph<T1> & g);
};

template <class T>
Graph<T>::Graph(int n, T inf_cost)
{
    infinity = inf_cost;
    size = n;
    graph = new T[n*n];
    for (int i = 0;i < n*n;i++)
        graph[i] = infinity;
}

template <class T>
Graph<T>::~Graph()
{
    delete [] graph;
}

template <class T>
void Graph<T>::link(int n1, int n2, T cost)
{
    graph[n1 + n2*size] = cost;
}

template <class T>
void Graph<T>::unlink(int n1, int n2)
{
    graph[n1 + n2*size] = infinity;
}

template <class T>
bool Graph<T>::linked(int n1, int n2)
{
    return graph[n1 + n2*size] != infinity;
}

template <class T1> ostream& operator<<(ostream &out, Graph<T1> & g)
{
    for (int i = 0; i < g.size;i++) {
        for (int j = 0; j < g.size;j++) {
            out << g.graph[i + j * g.size] << ", ";
        }
        out << "\n";
    }
    return out;
}

const char * show_yn(bool v)
{
    if (v)
        return "Yes";
    else
        return "No";
}

main()
{
    Graph<float>  g(3, -1.0);

    g.link(0, 1, 20.0);
    g.link(1, 2, 10.0);
    g.link(2, 1, 10.0);

    cout << g << endl;

    g.unlink(2,1);

    cout << g << endl;

    cout << "nodes 0 and 1 are linked? " << show_yn(g.linked(0,1)) << endl;
    cout << "nodes 2 and 1 are linked? " << show_yn(g.linked(2,1)) << endl;
}
