Remove minimum number of nodes to make graph disconnected - graph

Find the minimum number of nodes that needs to be removed to make graph disconnected( there exists no path from any node to all other nodes). Number of nodes can be 105

First of all, to find a node that is not needed to make the graph connected, you need to find a cycle. Once you find a cycle, then you know all those edges in those cycle are not needed. All the remaining edges in the graph are needed to hold the graph together, so you do a simple traversal of the graph and count the number of vertices connected to find the minimum number of nodes that needs to be removed to make graph disconnected. I'm not sure if this is the most efficient way, just the most efficient in my head. If V is the number of vertices and E is the number of edges, the time complexity will be somewhere around O(V + E) + O(V), since the initial cycle finding is O(V + E) and the counting of the nodes is O(V). Since E >= V, the time complexity can be rounded to O(E), but with huge constant factors.

Consider the graph undirected.
totalDegree = sum of degree of all nodes.
while(totalDegree > 0) {
Remove the node with highest degree and it's edges.
Update degree count of each node.
totalDegree = sum of degree of all remaining nodes.
}
remaining nodes are all disconnected
Trying to think of a case where it will not give the min number of nodes.

Related

How to efficiently determine which nodes can leave a graph while maintaining connectedness?

Suppose I have a graph with node weights, for example:
If a node has weight -1, it is "happy". If a node has positive weight, it is "unhappy", and wants to leave the graph.
How do I efficiently calculate which nodes I should kick out of the graph in order to minimize unhappiness (i.e., total graph weight), while making sure that the graph remains connected?
For instance, in this case, I can't get rid of the 10, 8, and 10 nodes, since that would disconnect the graph. The optimal solution in this case seems to be 10 + 8 + 5 = 23.
Small correction : the optimal solution in your example is 2 + 10 + 8 + 5 = 25. Nothing prevents you from removing all but connecting "unhappy" nodes.
On the discussion about bridge : bridge are edges, here you remove nodes. This makes a big difference : when removing edges, the nodes remains, and thus you cannot remove too many of them. When removing nodes, their attached edges are removed too, and you can be much more aggressive. So much that you only need to keep path between clusters of "happy" nodes. Everything else is removed.
How do you do that ?
Replace each cluster of happy nodes (happy nodes that are connected) by one happy node. (keep track of the replaced nodes)
For each edge between an happy and an unhappy node in the starting graph, make an edge between the node representing the cluster of the happy node, and the same unhappy node. The weight is the same as the original weight.
For each pair of happy nodes (representing the original clusters), find the shortest path between them. If this path pass through a third happy node, ignore it. Else, make an edge between the two happy nodes, with a weight equal to the total weight of the shortest path. (keep track of the nodes making the path)
Remove every unhappy node
Find the MST (minimum spanning tree) of the graph. Only keep the selected edges.
Replace each remaining edge of your graph by the path it represents
Replace each happy node by the cluster of happy nodes it represents
I tried to keep this solution in a high language, I can edit it to be more rigorous if needed.

How to generate n edges each between m nodes

I'm having trouble conceptualizing my problem. But essentially if I have m nodes, and want to generate no more than n connections for each node. I also want to ensure that there is a always a path from each node to any other node. I don't care about cycles.
I don't have the proper vocabulary to find this problem already existing though I'm sure it has to exist somewhere.
Does anyone know of a place where this problem is explained, or know the answer themselves?
The simplest way is to construct a Spanning Tree to ensure that all nodes are connected, then add edges that don't violate the maximum number of edges per node until you have the target number of them. In pseudocode:
// nodes[] is a list of all m nodes in our graph
connected_nodes = nodes[0];
// add nodes one by one until all are in the spanning tree
for next_node = 1 to (m-1)
repeat
select node connected_nodes[k] // randomly, nearest, smallest degree, whatever
until degree(k) < n // make sure node to connect to does not violate max degree
add edge between nodes[next_node] and new node connected_nodes[k]
add nodes[next_node] to connected_nodes[]
end for
// the graph is now connected, add the desired number of edges
for e = m+1 to desired_edge_count
select 2 nodes i,j from connected_nodes, each with degree < n
add edge between nodes i and j
end for

The number of connected (!) subgraphs is exponential?

i want to show that for an example graph family the nummer of connected subgraphs grows expnential with n.
That is easy to show for a complete graph, because a complete graph has
n(n-1)/2 = n over 2
edges. One edge is either in the subgraph or not. Therefore, every subgraph can be enumerated with a binary number of the length
2^(n over 2)
and because its a completed graph, every subgraph is connected.
But lets assume for example we want to show that the number of connected subgraphs in a 3- or 4-regular graph grows also exponential. We can enumerate the subgraphs in the same manner. But we have to exclude a lot of them, because they are not connected.
How can we do that? Is there a way to distinguish all connected subgraphs from the not connected ones?
Greetings and thanks for your thoughts
This idea is easy to prove for certain families of graphs, and in particular families of graphs with a high "Edge-Connectivity" (see https://en.wikipedia.org/wiki/K-edge-connected_graph).
For an edge-connectivity greater than k, you can always choose any k vertices for removal and generate a connected graph. Hence, you get at least Summation(j = 1 .. k; E-choose-k) graphs where E is the total number of edges. Let k > (E/m) for some constant m.
Then indeed, the number of sub-graphs will grow exponentially.

Remove minimum number of vertices to make all the vertices isolated

I have a undirected connected graph and I want to isolate all of its vertices by removing not edges but vertices, I want to keep the number of vertex that I remove to the minimum. I know to achieve this I must remove the vertices with the highest degree every time until the graph becomes disconnected. But I need to write a Java program for it and I do not know how to keep track of the vertex with highest degree and which data structure to use. I am given the following inputs.
{V, E}: Number of vertices and Edges respectively.
{A - B}: Vertex pair specifying an edge
Sample input:
4 2
1-2
3-4
Sample Output: 2 (that is the minimum number of vertices that need to be removed to make the vertices isolated)
constraints:
1 <= V <= 10^5
1 <= E <= 3 * 10^5
I second the idea that greedy algorithm is not always optimal here, even though the task is to isolate the vertices, not to disconnect the graph.
The problem here is the Vertex cover problem, and it is NP-hard.
For a quick counter-example consider this graph taken from here:
A greedy algorithm would start at the root, but that would take 4 vertices instead of optimal 3.
I would start of with the following DS:
class Node
{
int ID;
int NumberOfNeighbors;
List<int> NeighborIDs;
}
You then go on to keep all the Nodes in a maximum heap (where the key is NumberOfNeighbors).
Your algorithm should go something like:
int numberOfDeletedNodes = 0;
While (!heap.Empty)
{
node = heap.PopTop();
foreach (int ID in node.NeighborIDs)
{
tempNode = heap.Extract(ID);
tempNode.NumberOfNeighbors--;
tempNode.NeighborIDs.Remove(node.ID);
if (tempNode.NumberOfNeighbors != 0)
heap.Insert(tempNode);
}
numberOfDeletedNodes++;
}
I probably missed some end cases or something, but the general idea is to remove the node with the most neighbors, take care of all the neighbors*, and keep going until the heap is empty.
* Important: if the neighbors has no more neighbors of its own, it doesn't go back in.

What is the most amount of edges a directed graph can have without having a cycle?

Working on a graph, and this information would be useful, but it is hard to calculate. Thanks!
Attempted solution: Run a BFS and for each subsequent layer add an edge from all vertices of one BFS layer to all vertices of the next BFS layer.
Your attempt would give the maximum number of edges. Another way to look at it is to number the vertices 1 through n, and have an edge connecting each vertex to all higher numbered vertices, for a total of n(n-1)/2 edges.
To see that you can’t have any more edges, you just have to realize that once you have more than n(n-1)/2 edges, there must be some pair of vertices connected to each other in each direction, forming a cycle.

Resources