Find path between 2 vertices with x red vertices - algorithm

I've tried a couple of approaches and they all ended in a dead end.
The question:
Given a G=(V,E) a directed unweighted graph in which every vertex is colored red or blue.
Let there be vertices s and t from V. Describe an algorithm that would find a path between s and t which would hold the least red vertices. Explain the algorithm, prove it and show its complexity.
I've thought of 2 approaches and discarded both:
Use an adjacency list sorted by colors (blue first red last) and run a DFS - bad idea
Set the weight of each edge from a red vertex to 2 and blues to 1 and run Dijkstra - found a counterexample
I would really be happy to get some help with the right direction. I prefer NOT to get full answers but rather hits/tips.

Consider setting weight=1 for any edge that goes to a red vertex. Then show that the cost of a path from s with n red vertices is either n or n-1, depending on the color of s.

Well I've found an answer to this question, not me but a friend of mine after I showed him the weighted way to do it.
Instead of using one queue in the BFS algorithm we will use 2 queues: one for the blue vertices and one for the red vertices.
we check what color is S and add it to the right queue, as long as queue of the blue vertices is not empty we dequeue from it and continue the regular BFS if we encounter a red vertex we enqueue it to the red queue and if we find a blue vertex we enqueue it to the blue queue.
if the blue queue is empty we dequeue from the red queue.
eventually the array pi[|V|] will hold a backwards representation to vertex v with least of red vertices.
since there is no real change to the BFS algorithm and not to it's data structures the proof of correctness holds and the time complexity is O(|V|+|E|) as in BFS.
thanks for the help guys!

Related

Find a minimum distance with a number of even green edges

Hi I'm a computer science student, in my second year. During my studies, I got stuck with a question I couldn't solve, a question I was exposed to in order to expand my knowledge.
Question: There is an undirect graph, with edges of positive weight, I have to find I am the minimum distance between, in addition The graph has 2 types of edges - blue and green. I need to find a minimum distance between and also the number of its green edges in the tree is even.
I was thinking of an algorithm based on the Dijkstra algorithm.
Let's start from s
Each time we go to the bow with the minimum number.
If we have to go to a green vertex - right after that we try to go - to another green vertex.
I tried to draw my idea but it didn't work properly.
Why doesn't my idea work properly? what am I missing? Thanks for the help.
I would construct a new graph.
For each vertex i in the original graph, construct two vertices in the new graph numbered 2i and 2i+1.
For each blue edge i to j, construct edges 2i to 2j and 2i+1 to 2j+1.
For each green edge i to j, construct edges 2i to 2j+1 and 2i+1 to 2j.
Then Dijkstra's algorithm on the new graph from 2i to 2j will tell you the shortest distance from vertex i to j with an even number of green edges. (2i to 2j+1 will tell the shortest distance with an odd number of green edges.)
The idea is that we switch from the even graph to the odd graph whenever we traverse a green edge.
Your idea sounds like it only considers paths with two consecutive green edges. This will probably work for some graphs, but not all as in some case the optimum route may not include consecutive green edges.
UPDATE
For the graph in your comment:
the new graph looks like:

Algorithm for Finding Graph Connectivity

I'm tackling an interesting question in programming. It is this: we keep adding undirected edges to a graph, until the graph (or subgraph) is connected (i.e. we can use some path to get from each vertex to any other vertex in that subgraph). We stop as soon as the graph is connected.
For example if we have vertices 1,2,3 and 4 and we want the subgraph 1,2,3 to be connected.
Let's say we have edges (3,4), then (2,3), then (1,4), then (1,3). We only need to add in the first 3 edges for the subgraph to be connected, then we stop (edge 1,3 isn't needed).
Obviously I can run a BFS every time an edge is added to see if we can reach the required vertices, but if there are say m edges then we would potentially have to run BFS m times which seems too slow. Any better options? Thanks.
You should research the marvelous "Disjoint-set data structure" and the corresponding union - find algorithm. It can seem magical, but the worst case time and space complexity are tiny, O(α(n)) and O(n) respectively, where α is the inverse Ackerman function.
You can run just one time the BFS to find connected components. Then, each time you add an edge, if it is between vertices of two different components, you can merge them by a reference. So, the complexity of this algorithm is |V| + |E|.
Notice that the implementation of this method should be done by some reference techniques, especially to update the component number of the vertices.
I would normally do this using a disjoint set structure, as Doug suggests. It would be like Kruskal's algorithm for finding the minimum spanning tree, except you process edges in the given order.
If you don't need a spanning tree as output, though, then you can do this with an incremental BFS or DFS:
Pick any vertex, and find the vertices connected to it with BFS or DFS. Color these vertices red. If you start with no edges, of course, then there will be only one red vertex at this stage.
As you add edges, don't do anything else until you add an edge that connects a red vertex to a non-red vertex. Then run BFS or DFS, excluding the new edge, to find all the new vertices that will connect to the red set. Color them all red.
Stop when all vertices are red.
This is a little simpler in practice than using disjoint set, and takes O(|V|+|E|) time, since each vertex will be traversed by exactly one BFS/DFS search.
It does the work in chunks, though, so if you need each edge test to be fast individually, then disjoint set is better.

If topological sort uses DFS, how can it succeed on disconnected graphs?

There's a gap in my knowledge but I'm not sure exactly where. Topological sorting can be done using depth first search, as wikipedia explains. However I've only seen depth first search implemented for trees, where as topological sort is for DAGs.
is a tree a special case of a DAG where the implied direction of the edges is from the root node down
is the algorithm used for topological sort not really doing DFS, only something a lot like it?
For example, topological sort can handle disconnected graphs where as DFS cannot traverse a node with no edges connecting it...can it?
Because when used for topological sort you do a DFS on every nodes. If one of the children is already visited by a previous DFS (colored black). Then it is already pushed in the output vector and so you the dependency is already done.
Quoting your link (emphasis mine):
The algorithm loops through each node of the graph, in an arbitrary order, initiating a depth-first search ...
As the wikipedia article is a bit confusing (in my opinion) I will try to better describe the algorithm:
V: set of vertices
E: set of edges
E.adj(v): set of vertices adjacent to vertex v
0 function topological_sort(V,E):
1 for v in V:
2 paint v white
3
4 for v in V:
5 if v is white:
6 dfs(v)
7 function dfs(v):
8 paint v grey
9 for child in E.adj(v)
10 if child is white:
11 dfs(child)
12 paint v black
13 push v to output
We can easily compute the complexity:
We paint a vertex white, grey and black once per vertex: O(V)
We check the color of the vertex at line 5 once per vertex: O(V)
We check the color of the vertex at line 10 once per edge: O(E)
We push the vertex to output at line 13 once per vertex: O(V)
So the final complexity is: O(V+E). It is pretty efficient.
One of the strength of this algorithm is that it doesn't need to modify the input graph. We can easily implement coloring by a temporary hashtable with a size in O(V). Some other topological sort algorithm requires to destroy the graph when they proceed (by removing edges). This would require to copy the graph before running the toplogical sort if you still need the graph after the sort.
You might wish to try to add a new "source" node to your graph, and connect it with each and every other nodes with a directed edge. Then start your search/traverse from this new node. This approach might or might not suit your needs.

Prove that a graph is bipartite

Given a graph G in which every edge connects an even degree node with an odd degree node. How can i prove that the graph is bipartite?
Thanks in advance
This is the Welsh-Powell graph colouring algorithm:
All vertices are sorted according to the decreasing value of their degree in a list V
Colours are ordered in a list C
The first non-coloured vertex v in V is coloured with the first available colour in C. "Available" means a colour that has not previously used by this algorithm
The remaining part of the ordered list V is traversed and the same colour is allocated to every vertex for which no adjacent vertex has the same colour
Steps 3 and 4 are applied iteratively until all the vertices have been coloured
A graph is bipartite if it is 2-colourable. This intuitive fact is proven in Cambridge Tracts in Mathematics 131.
This is, of course, the cannon with which to shoot a mosquito. A graph is bipartite iff its vertices can be divided into two sets, such that every edge connects a vertex from set 1 to one in set 2. You already have such a division: each edge connects a vertex from the set of odd-degree vertices, to a vertex in the set of even-degree vertices.
Because by definition you already have two disjoint sets of vertices such that the only edges go between a vertex in one set and a vertex in the other set.
The even degree nodes are one set, and the odd degree nodes are the other set.
Pick any node, put it in set A. Take all the nodes that link to it, put them in set B. Now for every node added, add all it's neighbors to the opposite set, and check for the ones that already belong to one of the sets that they are in the right set. If you get a contradiction then the graph is not bipartite.
If you run out of neighbors but there are still nodes left, pick again any node and continue the algorithm until you either have no nodes or you found a contradiction.
If by "prove", you mean "find out", the complete solution is here
Bipartite.java
It works by keeping two boolean arrays. A marked array to check if a node has been visited, and another colored array. It then does a depth first search, marking neighbors with alternate colors. If a neighbor is marked with same color, graph is not bipartite.

Finding a spanning tree using exactly k red edges in a graph with edges colored by red/blue in linear time

Given a graph G with red and blue edges and a constant K, devise a deterministic, linear time algorithm that finds a spanning tree of G with exactly K red edges (or returns False if such a spanning tree does not exist).
What we have done so far:
Let every red edge have weight of -1 and every blue edge have weight of 0.
Find a minimum spanning tree (using a standard linear time algorithm). So, we have a spanning tree T with minimal weight, meaning we used as many red edges as we can because red edges will only decrease the weight.
If there are less than K red edges in T, we return False.
If there are exactly K red edges, we are done, T is the answer.
If there are more than K red edges, we need to replace them with blue ones.
This is our problem, how do we do that in linear time?
Every blue edge added will create a cycle, so removing one red edge from the cycle will work but how can we ensue linearity in this way? Is this even a good approach?
HINTS
You can do this in linear time using two passes of Prim's algorithm. (Usually Prim's algorithm is not linear time, but when you only have two types of edge you do not need to spend time sorting edges).
Pass 1
In the first pass follow blue edges before red edges and mark any red edges that you are forced to take.
If you mark C edges in this process then we know that there must be at least C red edges in any spanning tree solution, so if C>K, it is impossible.
Pass 2
Suppose we have found C ( < K ) marked edges in the first pass.
In the second pass follow red edges before blue, until the total number of additional red edges reaches K-C. In the second pass you are also allowed to follow the red edges marked in the first pass (and these do not count towards your total).
If your additional red edges does not reach K-C then it is impossible.

Resources