Question: I have a large (≈ 20 million nodes) directed Graph with in-edges & out-edges. I want to figure out which parts of of the graph deserve the most attention. Often most of the graph is boring, or at least it is already well understood. The way I am defining "attention" is by the concept of "connectedness" i.e. How can i find the most connected node(s) in the graph?

In what follows, One can assume that nodes by themselves have no score, the edges have no weight & they are either connected or not. 

[This website suggest](http://skillicorn.wordpress.com/2010/02/11/a-gentle-introduction-to-finding-the-most-important-node-in-graph-connected-data/) some pretty complicated procedures like n-dimensional space, Eigen Vectors, graph centrality concepts, pageRank etc. Is this problem that complex?

Can I not do a simple Breadth-First Traversal of the entire graph where at each node I figure out a way to find the number of in-edges. The node with most in-edges is the most important node in the graph. Am I missing something here?

Answer: 
Not knowing the real problem your graph solves or the details of your graph, this may not be relevant. But, I suspect your basic solution will be inaccurate in two ways: tie-breaking and what I might call "megalomaniacs." In other words, if you're just counting inbound connections, you'll likely run into nodes with the "same" importance; but, I suspect the intention is that one should be more important. And, in some cases, you may have "islands" of nodes that are all highly interconnected amongst themselves, but loosely so with the majority, yielding nodes that appear much more important than they are (megalomaniacs).

The solution? Well ... Something like pagerank, I imagine!
Just by sketching this out on a piece of paper, I opted for the depth-first search. Why? Well, by using the idea mentioned above, of traversing the graph by following the **directed** edges, we can ideally keep track of how many times we visit a particular node by incrementing some stored integer. You could do it just as easily with breadth-first.

```
void search(node) {
    nodeInitial = pick a node
    for(nodeInitial:outgoingNodes as node) {
        node:visits++ // this is how you track in-edges
        if(node is unvisited) {
            search(node)
            node:visited = true
        }
    }
}

```

Part of the problem is that with a directed graph, you might have sub-graphs that are connected to themselves, but are not connected externally. Other parts of the graph might connect to these sub-graphs, but there may be no outgoing connections. Think of an island (or group of islands) that has 3 one-way inbound-only highways traveling towards it but no outgoing highways. I think this is the bigger challenge - how to go about selecting parts of the graph that are unvisited. The only way I can think to do this would be if the nodes themselves also keep track of what other nodes are pointing at them (incoming nodes). From there, you would need to modify the algorithm so that it chooses a new node from some incoming node after it's done a complete traversal of an entire sub-graph. Then hop over to that other sub-graph and traverse it until you need to jump to the next sub-graph, etc.

I think it would be easy enough to store the "most important" node with the most in-edges by simply creating a single, separate node object that would be updated as you traverse the graph. 

```
Node mostImportant = null

void search(node) {
    nodeInitial = pick a node
    if(!mostImportant) {
        mostImportant = nodeInitial
    }

    for(nodeInitial:outgoingNodes as node) {
        node:visits++ // this is how you track in-edges

        if(node.visits > mostImportant.visits)
            mostImportant = node

        if(node is unvisited) {
            search(node)
            node:visited = true
        }
    }
}

```