Find minimum steps to reach the end of graph - c++

Given a directed graph which has nodes from 1 to N where each node has a color(blue/red) which is given to us. Now nodes are connected and each edge has some weight. We have to reach N from 1 such that in the path abs(x-y)<=k where x is the number of red nodes and y is the number of blue nodes and k is some integer value.
I tried solving using the Dijkstra shortest path algorithm but that will work only when there is no condition on no. of blue and red balls. So how should things proceed with Dijkstra or this requires something else?

Related

Shortest paths problem with one alteration

Let's say i have a directed graph G(V,E) with positive integer weights at it's edges.What i need to do is find the shortest paths between all vertices using at most K(integer) reverse edges.What i mean by that is:If we are at edge u and there is only a directed edge from v to u we can use it as long as we have not used K reverse edges for this path.This has to be implemented in C++ and give the shortest paths as a result.
I think the main approach to this problem is to conceptually create K+1 copies of the graph where each copy has one reverse edge,copy G_0 has one G_1 two etc.I could then run dijkstra in this graph and find the shortest path from a vertex to all others using as much as K reversed edges.This could be done V times(like johnsons algorithm)to find all possible shortest paths.My question is:how could this be implemented in c++?I excpect we don't have to create this multigraph but i can't see how it can be done otherwise.
If you know Dijkstra, you know that every vertex has a tentative distance label (initially infinite, except for the source) and you process the vertices in order of that tentative distance by "relaxing" their arcs, that is, updating the tentative distances of their neighbors.
If you allow for a number of arcs to be travelled in the wrong direction, I would go for a dynamic programming approach and have K labels for each vertex with the following semantics: Label 0 is the classic Dijstra label, Label 1 is the minimum distance from the start on a path with at most one reverse arc and so on.
Now, if I am correct, all you got to do is start with infinite labels and labels 0 for the source. Process labels instead of arcs and (again) start with the minimum tentative distance.
In contrast to the original, relaxing reverse arcs is allowed, but will update the K+1 label of the other side of the arc, while relaxing arcs in their normal direction will update the Kth label.

how to find S or less nodes in tree with minimum distance? [duplicate]

Given an unoriented tree with weightless edges with N vertices and N-1 edges and a number K find K nodes so that every node from a tree is within S distance of at least one of the K nodes. Also, S has to be the smallest possible S, so that if there were S' < S at least one node would be unreachable in S' steps.
I tried solving this problem, however, I feel that my supposed solution is not very fast.
My solution:
set x=1
find nodes which are x distance from every node
let the node which has the most nodes in its distance be one of the K nodes.
recompute for every node whilst not counting already covered nodes.
do this till I find K number of K nodes. Then if every node is covered we are done else increase x.
This problem is called p-center, and you can find several papers online about it such as this. It is indeed NP for general graphs, but polynomial on trees, both weighted and unweighted.
For me it looks like a clustering problem. Try it with the k-Means (wikipedia) algorithm where k equals to your K. Since you have a tree and all vertices are connected, you can use as distance measurement the distance/number of edges between your vertices.
When the algorithm converts you get the K nodes which should be found. Then you can determine S by iterating through all k clusters. There you calculate the maximum distance for every node in the cluster to the center node. And the overall max should be S.
Update: But actually I see that the k-means algorithm does not produce a global optimum, so this algorithm wouldn't also produce the best result ...
You say N nodes and N-1 vertices so your graph is a tree. You are actually looking for a connected K-subset of nodes minimizing the longest edge.
A polynomial algorithm may be:
Sort all your edges increasing distance.
Then loop on edges:
if none of the 2 nodes are in a group, create a new group.
else if one node is in 1 existing goup, add the other to the group
else both nodes are in 2 different groups, then fuse the groups
When a group reach K, break the loop and you have your connected K-subset.
Nevertheless, you have to note that your group can contain more than K nodes. You can imagine the problem of having 4 nodes, closed two by two. There would be no exact 3-subset solution of your problem.

Minimum path to connect k nodes in a graph with n nodes

Given a graph with n nodes and n-1 edges, find the lowest amount of edges needed to connect k nodes. You are given m numbers k <= n for which you have to solve the problem. The edges are unweighted and the graph does not necessarily describe a binary tree.
For a graph with n=5 and k=4, a possible path could be 1-2-5-2-3.
My approach was a greedy method in which I start from the node with the highest rank and try to add edges from there, but I did not have much success in trying to formulate an algorithm.
Try to find longest path in your tree, you will take every edge on that route once, than choose random node that has an edge, that connect that node to already choosen elements. So find longest path in your tree if that path has k or more nodes it is the end, you choose element on that path, every edge will be taken once Else choose a random, untaken already node, that is connected by any edge directly to one of already taken nodes, as long as you do not have k nodes in your collection.

Subset of vertices

I have a homework problem and i don't know how to solve it. If you could give me an idea i would be very grateful.
This is the problem:
"You are given a connected undirected graph which has N vertices and N edges. Each vertex has a cost. You have to find a subset of vertices so that the total cost of the vertices in the subset is minimum, and each edge is incident with at least one vertex from the subset."
Thank you in advance!
P.S: I have tought about a solution for a long time, and the only ideas i came up with are backtracking or an minimum cost matching in bipartite graph but both ideas are too slow for N=100000.
This may be solved in linear time using dynamic programming.
A connected graph with N vertices and N edges contains exactly one cycle. Start with detecting this cycle (with the help of depth-first search).
Then remove any edge on this cycle. Two vertices incident to this edge are u and v. After this edge removal, we have a tree. Interpret it as a rooted tree with the root u.
Dynamic programming recurrence for this tree may be defined this way:
w0[k] = 0 (for leaf nodes)
w1[k] = vertex_cost (for leaf nodes)
w0[k] = w1[k+1] (for nodes with one descendant)
w1[k] = vertex_cost + min(w0[k+1], w1[k+1]) (for nodes with one descendant)
w0[k] = sum(w1[k+1], x1[k+1], ...) (for branch nodes)
w1[k] = vertex_cost + sum(min(w0[k+1], w1[k+1]), min(x0[k+1], x1[k+1]), ...)
Here k is the node depth (distance from root), w0 is cost of the sub-tree starting from node w when w is not in the "subset", w1 is cost of the sub-tree starting from node w when w is in the "subset".
For each node only two values should be calculated: w0 and w1. But for nodes that were on the cycle we need 4 values: wi,j, where i=0 if node v is not in the "subset", i=1 if node v is in the "subset", j=0 if current node is not in the "subset", j=1 if current node is in the "subset".
Optimal cost of the "subset" is determined as min(u0,1, u1,0, u1,1). To get the "subset" itself, store back-pointers along with each sub-tree cost, and use them to reconstruct the subset.
Due to the number of edges are strict to the same number of vertices, so it's not the common Vertex cover problem which is NP-Complete. I think there's a polynomial solution here:
An N vertices and (N-1) edges graph is a tree. Your graph has N vertices and N edges. Firstly find the awful edge causing a loop and make the graph to a tree. You could use DFS to find the loop (O(N)). Removing any one of the edges in the loop would make a possible tree. In extreme condition you would get N possible trees (the raw graph is a circle).
Apply a simple dynamic planning algorithm (O(N)) to each possible tree (O(N^2)), then find the one with the least cost.

How do I find the shortest path that covers all nodes in a directed cyclic graph?

I need an example of the shortest path of a directed cyclic graph from one node
(it should reach to all nodes of the graph from a node that will be the input).
Please if there is an example, I need it in C++, or the algorithm.
EDIT: Oops, misread the question. Thanks #jfclavette for picking this up. Old answer is at the end.
The problem you're trying to solve is called the Travelling salesman problem. There are many potential solutions, but it's NP-complete so you won't be able to solve for large graphs.
Old answer:
What you're trying to find is called the girth of a graph. It can be solved by setting the distances from a node to itself to infinity and using the Floyd-Warshall algorithm. The length of the shortest cycle from node i is then just the entry in position ii.
In the unweighted case: Breadth first search.
In the weighted case: Dijkstra's.
In Pseudocode:
//INPUT: graph G = (V,E)
//OUTPUT: shortest cycle length
min_cycle(G)
min = ∞
for u in V
len = dij_cyc(G,u)
if min > len
min = len
return min
//INPUT: graph G and vertex s
//OUTPUT: minimum distance back to s
dij_cyc(G,s)
for u in V
dist(u) = ∞
//makequeue returns a priority queue of all V
H = makequeue(V) //using dist-values as keys with s First In
while !H.empty?
u = deletemin(H)
for all edges (u,v) in E
if dist(v) > dist(u) + l(u,v) then
dist(v) = dist(u) + l(u,v)
decreasekey(H,v)
return dist(s)
This runs a slightly different Dijkstra's on each vertex. The mutated Dijkstras
has a few key differences. First, all initial distances are set to ∞, even the
start vertex. Second, the start vertex must be put on the queue first to make
sure it comes off first since they all have the same priority. Finally, the
mutated Dijkstras returns the distance back to the start node. If there was no
path back to the start vertex the distance remains ∞. The minimum of all these
returns from the mutated Dijkstras is the shortest path. Since Dijkstras runs
at worst in O(|V|^2) and min_cycle runs this form of Dijkstras |V| times, the
final running time to find the shortest cycle is O(|V|^3). If min_cyc returns
∞ then the graph is acyclic.
To return the actual path of the shortest cycle only slight modifications need to be made.
For non weighted graph, BFS will do the job. Since there is potential cycle in your graph, you need to keep track of visited node (you sort of need to do this for BFS anyway).
For weighted graph, bellman–Ford algorithm can be used. It is also able to detect cycles.