questo l'ho fatto io l'altro giorno
codice:
package pacnet.shared;

import java.util.ArrayList;
import java.util.Iterator;

/**
 *
 * @author 667002985
 * @param <T>
 */
public class Graph<T> {

    private ArrayList<Vertex<T>> vertexList = new ArrayList<Vertex<T>>();
    private ArrayList<ArrayList<Vertex<T>>> adjList= new ArrayList<ArrayList<Vertex<T>>>();
    private boolean directed;

    /**
     *
     * @param directed
     */
    public Graph(boolean directed) {
        this.directed = directed;
    }

    /**
     * 
     * @return Array of vertexes
     */
    public Vertex<T>[] getVertexs() {
        Vertex<T>[] ret = new Vertex[vertexList.size()];
        return vertexList.toArray(ret);
    }

    /**
     *
     * @param vertex
     */
    public void addVertex(Vertex<T> vertex) {
        if (!exists(vertex))
        {
            vertexList.add(vertex);
            adjList.add(new ArrayList<Vertex<T>>());
        }
    }

    /**
     *
     * @param vertex
     */
    public void removeVertex(Vertex<T> vertex) {
        int index = vertexList.indexOf(vertex);
        vertexList.remove(index);
        adjList.remove(index);
    }

    /**
     * Connects two vertexs togheter
     * @param from start vertex
     * @param to end vertex
     */
    public void connect(Vertex<T> from, Vertex<T> to) {
        //controllo se i vertici esistino nel grafo? si/no?
        //adds vertex if doesn't exists

        if (!isConnected(from, to))
        {
            addVertex(from);
            addVertex(to);

            //from and to are two object with same contents of present vertex.
            //So i have to pick the reference of my vertex, becouse from and to
            //counldn't have the me same reference.
            int i = vertexList.indexOf(to);
            to = vertexList.get(i);

            //gets the vertex array index
            i = vertexList.indexOf(from);
            //gets its adj
            ArrayList<Vertex<T>> lst = adjList.get(i);
            lst.add(to);

            if (!isDirected())
            {
                connect(to,from);
            }
        }

        /*for (Iterator vertexIterator = this.vertexList.iterator(); vertexIterator.hasNext();) {
            Vertex<T> toVerify = (Vertex<T>) vertexIterator.next();
            if (toVerify.equals(from)) {
                int index = vertexList.indexOf(toVerify);
                ((ArrayList<Vertex<T>>) adjList.get(index)).add(to);//should append...
            }
        }*/
    }

    /**
     * Disconnects two vertexs
     * @param from
     * @param to
     */
    public void disconnect(Vertex<T> from, Vertex<T> to)
    {
        if (isConnected(from, to))
        {
            int i = vertexList.indexOf(from);
            try
            {
                ArrayList<Vertex<T>> list  = adjList.get(i);
                list.remove(to);
                if (!isDirected())
                {
                    //if the graph's not directed, remove the reverse edge.
                    disconnect(to,from);
                }
            }
            //catched if i == -1
            catch(ArrayIndexOutOfBoundsException aioobe)
            {
            }
        }
    }

    /**
     * Returns adjacent vertexes list of given vertex
     * @param v
     * @return
     */
    public ArrayList<Vertex<T>> adjacents(Vertex<T> v)
    {
        int i = vertexList.indexOf(v);
        return adjList.get(i);
    }

    /**
     * Checks whether a node in in the graph
     * @param node
     * @return TRUE if the node is in the graph, FALSE otherwise
     */
    public boolean exists(Vertex<T> node)
    {
        return vertexList.contains(node);
    }


    /**
     *
     * @param from
     * @param to
     * @return true if exists an edge from 'from' vertex to 'to' vertex , false otherwise
     */
    public boolean isConnected(Vertex<T> from, Vertex<T> to) {
        //li devo controllare???
        for (Iterator vertexIterator = this.vertexList.iterator(); vertexIterator.hasNext();) {
            Vertex<T> toVerify = (Vertex<T>) vertexIterator.next();
            if (toVerify == from) {
                int index = vertexList.indexOf(toVerify);
                return ((ArrayList<Vertex<T>>) adjList.get(index)).contains(to);
            }
        }
        return false;
    }

    /**
     *
     * @return true if the graph is directed, false otherwise
     */
    public boolean isDirected() {
        return directed;
    }

    /**
     * Sets for each vertex the given vertex state
     * @param visited New visited state
     */
    public void visited(boolean visited)
    {
        for(Vertex<T> v : vertexList)
        {
            v.visited(visited);
        }
    }



    /**
     * 
     * @param <T>
     */
    public static class Vertex<T> {

        private T content;
        private boolean visited = false;

        /**
         *
         * @param content
         */
        public Vertex(T content) {
            this.content = content;
        }

        /**
         * Returns vertex's information
         * @return a generic object
         */
        public T getContent() {
            return content;
        }

        /**
         *
         * @param val
         */
        public void setContent(T val) {
            this.content = val;
        }

        public boolean isVisited() {
            return visited;
        }

        public void visited(boolean val) {
            this.visited = val;
        }
    }
}