PointGraph (PointUndirectedGraph, PointDirectedGraph, PointTree)

This PR changes the way we define a `PointGraph`. The old `PointGraph` class (mainly used in landmarks) is now replaced by `PointUndirectedGraph`. There are also `PointDirectedGraph` and `PointTree`. This way of defining the `PointGraph` family classes is now consistent with the way the `Graph` family is defined (`UndirectedGraph`, `DirectedGraph`, `Tree`).

Finally, this PR adds a function that checks whether the `adjacency_array` provided in the `Tree` class actually represents a tree, otherwise an error is raised.
could this computation take time? If so just have it as a method!
```python
potential_tree.is_tree()
```
let's me know that this could potentially be (relatively expensive), avoids me doing stuff like:
```python
if x.is_tree:
   ...
elif x.is_tree and y.some_state()
   ...
```