i want to determine if a given graph has the structure i want. The structure i want is that if the given graph's tree's roots form a cycle then the output is true, else is false.
Here’s an example graph:
It has 3 trees and the roots 1,5,4 form a cycle.
Also this is an example that should not pass because it does not contain tree's which root's form a cycle:
How can I decide given the vertices which trees should i search?
This is the code so far, printing the adjacency list of a given graph.
#include <iostream>
#include <vector>
using namespace std;
void addEdge(vector<int> vec[], int u, int v)
{
vec[u].push_back(v);
}
void printGraph(vector<int> vec[], int j)
{
cout << "Graph's adjacent list: \n";
for (int v = 0; v < j; ++v)
{
if (vec[v].size() == 0) continue;
cout << "Head(" << v << ")";
for (auto x = vec[v].begin(); x != vec[v].end(); x++)
cout << " -> " << *x;
cout << "\n" ;
}
}
int main()
{
int V = 10;
vector<int> vec[V];
addEdge(vec, 6, 3);
addEdge(vec, 7, 1);
addEdge(vec, 8, 9);
addEdge(vec, 6, 4);
addEdge(vec, 5, 1);
addEdge(vec, 1, 9);
addEdge(vec, 2, 5);
addEdge(vec, 1, 4);
addEdge(vec, 5, 4);
printGraph(vec, V);
return 0;
}
Your question is how to tell whether a given graph
contains exactly one cycle,
where each node on the cycle is the root of a tree.
The good news is that, assuming your graph is connected, then if property (1) is true, then so is property (2)! To see why this is, imagine deleting any edge from that cycle. Now you have a connected graph with no cycles, which is a tree. That means that every node, not just the ones on the cycle, can then be thought of as the root.
The nice part about this is that there’s a really nice algorithm for determining whether a graph is connected and contains exactly one cycle. First, count the number of edges in the graph. If the graph is indeed connected and contains exactly one cycle, then the number of edges should be exactly equal to the number of nodes. (A tree has one more node than edge, and you’ve added in an edge). If that isn’t the case, then stop - the answer is no.
From there, you know you have the right number of nodes and edges. You just need to check whether the graph is connected, and you can do that with a DFS or BFS over the graph.
The nice part about this is that if you implement it correctly, the runtime will be O(n), where n is the number of nodes, independently of the number of edges. After all, if you see more than n edges, you can stop the search.
Hope this helps!
Related
Introduction
Good day,
I am looking for a grouping algorithm that can do the following:
Let's suppose I have an array of sorted numbers (without any multiple occurences). For example, {0, 2, 5, 6, 7, 10}.
I want to make groups from that array, such that:
I minimize the number of groups,
Each groups needs to contain numbers that are linked with at most n - 1 "bonds" (for example, n = 3, 0 and 2 are neighbours but not 0 and 3).
EDIT
In other words, when I say neighbours, I should speak about integer distance. For example, the distance of 0 to 2 i 2 (and vice versa). The distance of 0 to 3 is 3. You could think of the problem like a set of 1D points, and one needs to find the minimal number of centers, which center contains points that are distant to it of n/2. I hope it is more clear like that.
The example has multiple groups possible but the best along conditions 1 and 2 (n = 3) is {{0, 2}, {5, 6, 7}, {10}}. {{0}, {2, 5}, {6, 7}, {10}} has one group more than the best solution. The ideal solution would happen if all sorted numbers are continuous:
nb_groups* = ceil(v.size() / n);
In addition, there might be multiple solution depending on the algorithm.
What I tried
For now, what I do is:
Compute the array of the distances between the neighbouring elemens,
Check neighbouring conditions with rests from the beginning of the vector to the end (see the code below).
It seems to work (to me), but I was wondering two things:
Does it really work for any cases (have maybe not tested all cases?)?
If so, could I optimize my implementation in a way (better than in.size() - 1 iteration ans with less memory consumption)?
Code
I was considering a function that takes the vector to group, and the max distance. This function would return the indices of the first element of the group.
#include <iostream>
#include <vector>
std::vector<int> groupe(const std::vector<int>& at, const int& n);
int main() {
// Example of input vector
std::vector<int> in = {0, 2, 5, 6, 7, 10, 11, 22, 30, 50, 51};
// Try to group with neighbouring distance of 3
std::vector<int> res = groupe(in, 3);
// Printing the result
for(const int& a : res) {
std::cout << a << " ";
}
}
std::vector<int> groupe(const std::vector<int>& at, const int& n) {
std::vector<int> out;
// Reste keeps tracks of a bigger neighbouring distance (in case we can look for another element to be in the group)
int reste(0);
size_t s = at.size() - 1;
for(int i = 0; i < s; i++) {
// Computing the distance between element i and i + 1
int d = at[i + 1] - at[i];
if(d >= n) {
if(reste == 0) {
out.push_back(i);
}
reste = 0;
} else {
if(reste == 0) {
out.push_back(i);
}
reste += d;
if(reste >= n) {
reste = 0;
}
}
}
if(reste == 0 || reste >= n) {
out.push_back(s);
}
return out;
}
OUTPUT
0 2 5 7 8 9
Note
If the original vector was not sorted, I guess we could have sorted it first and then achieved this step (or maybe there is another algorithm mor efficient?).
I thank you in advance for your time and help.
I am working on the LeetCode problem 987: Vertical Order Traversal of a Binary Tree:
Given the root of a binary tree, calculate the vertical order traversal of the binary tree.
For each node at position (row, col), its left and right children will be at positions (row + 1, col - 1) and (row + 1, col + 1) respectively. The root of the tree is at (0, 0).
The vertical order traversal of a binary tree is a list of top-to-bottom orderings for each column index starting from the leftmost column and ending on the rightmost column. There may be multiple nodes in the same row and same column. In such a case, sort these nodes by their values.
Return the vertical order traversal of the binary tree.
This is my code:
class Solution {
public:
vector<vector<int>> verticalTraversal(TreeNode* root)
{
map<int, map<int, vector<int> > > nodes; // actual mapping
queue<pair<TreeNode*, pair<int, int> > > q; // for storing in queue along with HD and level no.
vector<vector<int>> ans;
vector<int> cur_vec;
if(!root){
return ans;
}
q.push(make_pair(root, make_pair(0, 0)));
while(!q.empty()){
pair<TreeNode*, pair<int, int> > temp = q.front(); // for storing the queue.front value in temp
q.pop();
TreeNode* frontNode = temp.first;
int hd = temp.second.first;
int level = temp.second.second;
nodes[hd][level].push_back(frontNode->val);
if(frontNode->left)
q.push(make_pair(frontNode->left, make_pair(hd-1, level+1)));
if(frontNode->right)
q.push(make_pair(frontNode->right, make_pair(hd+1, level+1)));
}
for(auto i: nodes){
for(auto j: i.second){
for(auto k: j.second){
cur_vec.push_back(k);
}
}
ans.push_back(cur_vec);
cur_vec.resize(0);
}
return ans;
}
};
I've used a multidimensional map in my answer which maps horizontal distance to levels. It works for several test cases, but it fails to pass the test case when two nodes overlap each other and the smaller one has to come first.
For instance, here the correct output for one vertical line is [1,5,6] but mine is [1,6,5] (the overlapping nodes are 6 and 5):
What should I change to make it work?
In your final loop, you can just add a call to sort on the inner vector (that corresponds to a certain horizontal distance and certain level). It is in that vector you could get overlapping nodes.
So:
for(auto i: nodes){
for(auto j: i.second){
sort(j.second.begin(), j.second.end()); // <-- added
for(auto k: j.second){
cur_vec.push_back(k);
}
}
ans.push_back(cur_vec);
cur_vec.resize(0);
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Below is the C++ code for Kruskal's algorithm for finding the minimum cost spanning tree of a graph given by my instructor.
I did not understand the code well. I want to know exactly what part of the code is checking for formation of a cycle in the growing forest of included edges.
I also want to know that what exactly is the purpose of the parent[] array.
Also, is it a better way than checking for cycles using DFS (depth first search)?
Here is the code:
#include<stdio.h>
#include<stdlib.h>
int i, j, k, a, b, u, v, n, ne = 1;
int min, mincost = 0, cost[9][9], parent[9];
int find(int);
int uni(int, int);
int main()
{
printf("\n\tImplementation of Kruskal's algorithm\n");
printf("\nEnter the no. of vertices:");
scanf("%d",&n);
printf("\nEnter the cost adjacency matrix:\n");
for (i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
scanf("%d",&cost[i][j]);
if(cost[i][j] == 0)
cost[i][j] = 999;
}
}
printf("The edges of Minimum Cost Spanning Tree are\n");
while(ne < n)
{
for(i = 1, min = 999; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
if(cost[i][j] < min)
{
min = cost[i][j];
a = u = i;
b = v = j;
}
}
}
u = find(u);
v = find(v);
if(uni(u,v))
{
printf("%d edge (%d, %d) =%d\n", ne++, a, b, min);
mincost += min;
}
cost[a][b] = 999;
}
printf("\n\tMinimum cost = %d\n",mincost);
}
int find(int i)
{
while(parent[i])
i = parent[i];
return i;
}
int uni(int i,int j)
{
if(i!=j)
{
parent[j]=i;
return 1;
}
return 0;
}
Note:
I am aware that the code is messed up a bit and user input will result in failure in case the user enters a value more than 9, but I don't want to focus on that part without understanding how it works. I just know that it selects the minimum cost edge, checks it for the formation of the cycle and then sets its value to infinity (here 999). I don't know how and where it is checking for cycle formation. Please help by explaining.
The code inside the while loop in main finds the lightest edge that has not yet been considered. That edge is between nodes u and v. The edge can form a cycle only if u and v already belong to the same tree.
This:
u=find(u);
v=find(v);
finds the roots of the trees to which u and v belong. Then main passes those two roots to uni:
if(uni(u,v))
...
int uni(int i,int j)
{
if(i!=j)
{
parent[j]=i;
return 1;
}
return 0;
}
If the two roots are the same, the code does nothing, the edge is not used.
I want to know exactly what part of the code is checking for formation of a cycle in the growing forest of included edges. I also want to know that what exactly is the purpose of the parent[] array.
You seem to understand the general idea of Kruskal's algorithm, but not some of the more important details. In particular, I have to assume that you do not understand the central and essential use of a "disjoint set" (a.k.a. "set union" and other names) data structure in this algorithm. For if you did, you would surely recognize that in your code, that is the role served by the parent array. Even if you didn't guess from the name, the find() and uni() functions are a dead giveaway.
The code uses the disjoint set structure to track which groups of vertices are connected by the edges so far added to the graph. The find() function determines which set a given vertex belongs to, and candidate edges are rejected if the two vertices belong to the same set. The uni() function combines two sets into one when two subgraphs are joined by accepting an edge.
Also, is it a better way than checking for cycles using DFS (depth first search)?
Performance details depend somewhat on the implementation of disjoint set. The one here is particularly simple, but more sophisticated ones can reduce the amortized cost of searches, for a better performance bound on the algorithm overall than can be achieved by using DFS instead.
Alright. Before proceeding to the explanation feel free to take a second and read this wonderfully written tutorial on Kruskal's Algorithm over on HackerEarth so that you have a general idea of what to look for.
Now as for the algorithm:
Note: First of all ignore the first three lines, just look at the code in main and assume that all variables are declared before hand.
Now let's begin:
printf("\n\tImplementation of Kruskal's algorithm\n");
printf("\nEnter the no. of vertices:");
scanf("%d",&n);
printf("\nEnter the cost adjacency matrix:\n");
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&cost[i][j]);
if(cost[i][j]==0)
cost[i][j]=999;
}
}
Those first lines ask for the number of vertices and an adjacency matrix with the cost of each vertex to any other vertex. It also looks like that when there isn't any edge connecting 2 vertices the cost is set to 999 so that it doesn't bug the code when set at 0.
Here is what an adjacency matrix looks like.
Assume that your graph looks like this
The adjacency matrix would be the following:
1 2 3
_________
1| 0 0 11
2| 0 0 0
3| 11 6 0
Meaning that 1 is connected to 3 with cost 11. 2 isn't connected with any vertex and 3 is connected to 1 with cost 11 and to 2 with cost 6. The code above would change the above matrix to:
1 2 3
_____________
1| 999 999 11
2| 999 999 999
3| 11 6 999
So that the algorithm doesn't pick 0 as minimum cost. And avoids selecting non-connected vertices.
After that we have:
printf("The edges of Minimum Cost Spanning Tree are\n");
while(ne < n)
{
for(i=1,min=999;i<=n;i++)
{
for(j=1;j <= n;j++)
{
if(cost[i][j] < min)
{
min=cost[i][j];
a=u=i;
b=v=j;
}
}
}
u=find(u);
v=find(v);
if(uni(u,v))
{
printf("%d edge (%d,%d) =%d\n",ne++,a,b,min);
mincost +=min;
}
cost[a][b]=999;
}
printf("\n\tMinimum cost = %d\n",mincost);
Firstly you have to know that Kruskal's algorithm uses Connected Components to figure out whether 2 vertices are connected or not(this is also the reason why kruskal's algorithm doesn't create circles). So let's what the code does.
for(i=1,min=999;i<=n;i++)
{
for(j=1;j <= n;j++)
{
if(cost[i][j] < min)
{
min=cost[i][j];
a=u=i;
b=v=j;
}
}
}
This is somewhat straight forward. What it does is goes through the matrix and finds the smallest value in it. So for the example I gave it would first find 6.
So min=6, u=3(the starting vertex), v=2(the ending vertex). So now in order to understand what will follow you will have to READ about disjoint sets and connected components. Luckily for you there is a 10 min read tutorial again over at HackerEarth which will help you understand how Connected Components work. You can find it here.
So here is what's happening. The algorithm says the smallest cost right now is from 3->2 that costs 6. let's add this to the graph that we are building at the background with connected components and set the cost to 999 so we don't reconsider it. So here: u=find(u);
It goes to the parent array and checks at position 3(arr[3]) who is the parent? The answer is 3 since we haven't connected it to any other component yet. Next it does the same thing for 2(arr[2]) which also stays the same since we haven't connected it. To anything else. And then unifies them to one. That is the array now becomes:
[1, 2, 3] -> [1, 3, 3] (minCost is now equal to 6)
Then it adds min to minCost which is the answer. And changes the cost from 3->2 to 999 so we don't reconsider it.
It repeats that process so that we have:
// min=6, u=3, v=2
[1, 2, 3] -> [1, 3, 3] // minCost = 6
// min=11, u=1, v=3
[1, 3, 3] -> [1, 3, 1] // minCost = 17
// min=11, u=3, v=1 !!! CAREFUL NOW
Moving over to
parent of parent[3] == parent[1] meaning that they have the same parent so they are CONNECTED.
if(uni(u,v)) <-- This won't run since uni(3, 1) will return 0 meaning that they are connected so the min won't be added to minCost this time.
And this is where the algorithm ends. It prints a final cost of 17 and you are done. The ne variable is just there as a counter to make prints easier to understand.
I hope this helps you. Be sure to read the tutorials I linked they will really help you understand the logic because the Wonderful Kruskal's Algorithm.
The links mentioned above:
Kruskal's algorithm: https://www.hackerearth.com/practice/algorithms/graphs/minimum-spanning-tree/tutorial/
Connected Components: https://www.hackerearth.com/practice/data-structures/disjoint-data-strutures/basics-of-disjoint-data-structures/tutorial/
This structure will only contain exactly 256 unsigned chars.
The only operation possible is taking random characters from it and putting them in front of the structure.
For example:
A= 'abcdef'
Move character 2 to front
A= 'cabdef'
I first thought of using linked link so that it could work as a queue.
Thing is I heard that arrays are much faster than linked lists for these operations. Is this true?
A linked list will be O(1) and an array will be O(n) for a move operation as you have described. For small n the array will probably be faster, but the only way to know for sure is to benchmark.
In a case like this I would code what's clearest and only worry about efficiency if it proves to be a bottleneck.
P.S. I made an assumption that you already had a pointer to the character you want to move. If this is not the case, then finding the character will be O(n) in the linked list and you will lose any advantages it might have.
Use an array. The linked list will be huge and unwieldy for storage of char data.
A linked list would be a good approach since you don't need to move all the intermediate elements around. std::list works just fine, combined with splice(). You will need an iterator to the element you want to move to the front:
#include <list>
#include <iostream>
#include "prettyprint.hpp"
int main()
{
std::list<int> x { 1, 4, 6, 7, 2 };
auto i = x.begin(); std::advance(i, 2); // i points to 6
std::cout << x << std::endl; // [1, 4, 6, 7, 2]
x.splice(x.begin(), x, i);
std::cout << x << std::endl; // [6, 1, 4, 7, 2]
}
(Using the pretty printer for a quick demo.)
As others have said, whether that's more efficient that a random-access container depends on how you are tracking the element that you want to move.
Update: In light of Steve's remarks I should like to offer a raw C-array solution, too. It has the benefit that you can access it by position in O(1) time and that it requires minimum space:
char y[] = { 'a', 'c', 'Q', '%', '5' };
std::cout << pretty_print_array(y) << std::endl; // [a, c, Q, %, 5]
std::rotate(y, y + 2, y + sizeof(y));
std::cout << pretty_print_array(y) << std::endl; // [Q, %, 5, a, c]
The rotate call could be wrapped in a function:
template <typename T, size_t N>
void bring_forward(T (& a)[N], size_t p) { std::rotate(a, a + p, a + N); }
In C++, you can use a vector instead of array or linked list. The complexity of a Linked List is O(1) like #Mark Ransom said. With the vector, you can use the command rotate to perform the action you desire. The complexity is determined by the number of swaps.
From MSDN, how to use rotate:
const int VECTOR_SIZE = 8;
// Define a template class vector of strings
typedef vector<string> StrVector;
//Define an iterator for template class vector of strings
typedef StrVector::iterator StrVectorIt;
StrVector Tongue_Twister(VECTOR_SIZE);
StrVectorIt start, end, middle, it;
// location of first element of Tongue_Twister
start = Tongue_Twister.begin();
// one past the location last element of Tongue_Twister
end = Tongue_Twister.end();
// Initialize vector Tongue_Twister
Tongue_Twister[0] = "she";
Tongue_Twister[1] = "sells";
Tongue_Twister[2] = "sea";
Tongue_Twister[3] = "shells";
Tongue_Twister[4] = "by";
Tongue_Twister[5] = "the";
Tongue_Twister[6] = "sea";
Tongue_Twister[7] = "shore";
middle = start + 3; // start position for rotating elements
cout << "Before calling rotate" << endl;
// print content of Tongue_Twister
cout << "Try this Tongue Twister:";
for (it = start; it != end; it++)
cout << " " << *it;
// rotate the items in the vector Tongue_Twister by 3 positions
rotate(start, middle, end);
Or you can do it with arrays:
// create an array of 9 elements and rotate the entire array.
int myArray[SIZE] = { 7, 8, 9, 1, 2, 3, 4, 5, 6, };
std::rotate(myArray, myArray + 3, myArray + SIZE);
How fast is this? I don't know. I haven't benchmarked it. But it is much easier than having to manually swap elements of an array.
The array will be O(1) to find the item and O(n) to move it and the other items into the correct position. The linked list will be O(n) to find the item and O(1) to move everything to the right position. The complexity is the same either way.
They're both easy to implement, so implement both of them and run tests to see which one lets your program run faster with real-world data.
C++ arrays are linked lists, so moving an element to the front of your list is cheap, provided you already know where the element is (i.e. you have an iterator on it). Using a vector would cause the entire list to be shifted each time an element is pushed in front of it.
I've just implemented a threaded tree in C++, and now I'm trying to cout all the elements in order.
The tree was a binary sorted tree (not balanced) before I've threaded it.
I've tried doing this:
E min = _min(root); //returns the minimum element of the tree
E max = _max(root); //returns the maximum element of the tree
while (min != max)
{
std::cout << min << ", ";
min = _successor(root, min);
}
std::cout << max << ", ";
std::cout << std::endl;
but since the tree is now threaded, my successor function always returns the minimum of the whole tree (basically, it goes once in the right subtree, and then goes in the left subtree as many times as possible, until it finds a leaf.) So when I try to call this function, it only cout 1's (because 1 is the minimum value of my tree).
Also, I've tried something else:
E min = _min(root); //returns min element of the tree
E max = _max(root); //returns max element of the tree
Node* tmp = _getNode(root, min); //returns the node of the specified element, therefore the minimum node of the tree
while(tmp->data < max)
{
std::cout << tmp->data << ", ";
tmp = _getNode(root, tmp->data)->rightChild; //gets the right child node of tmp
}
std::cout << tmp->data << ", ";
However, by doing this, there are values that are ignored. (See image below)
(Green links have been added after the threading of the tree.)
If you see, for example, the node #6 never gets visited from the very last algorithm, because it's not the right child of any node in the tree...
Here's the output of the previous function:
1, 2, 3, 5, 7, 8, 11, 71
Does anyone have an idea of how I could fix this, or any tips for my problem?
Thanks
EDIT: After all I just had to traverse the tree from the minimum to the maximum AND modify my _predecessor and _successor methods, so they wouldn't check in subtrees that are threaded. :)
Hope it helps future readers.
Try
Node* n = _min(root);
while (n->right) {
cout << n->val << ", ";
n = _successor(n);
}
cout << n->val << endl;
This is basically your first code (note that I assume that the tree is non-empty as do you). This also won't give you a trailing ','.
The important thing is to get your successor function correct. It should be like this
Node* _successor(Node* n) {
if (is_thread(o, RIGHT)) return o->right;
return _min(o->right);
}
And for completeness
Node* _min(Node* n) {
while (!is_thread(o, LEFT)) n = o->left;
return n;
}
For both of these all the green arrows are threads.
I've never seen threaded trees before, but I'll take a stab at this anyway. To build an inorder traversal, you could approach the root of the tree from two directions at once:
Start at the root.
Follow all left links until you find one that points to null. That element is the tree's minimum value.
Follow all right links until you reach the root. If you've built the tree correctly, this should traverse every element in increasing order.
Repeat steps 2 and 3 in the opposite direction (find the max element, walk backwards).
Join these two lists with the root in the middle.
That's probably not the fastest algorithm but I think it'll produce a correct answer. And you didn't have to use recursion, which I guess is the whole point for using a threaded tree.
After all I just had to traverse the tree from the minimum to the maximum
AND
modify my _predecessor and _successor methods, so they wouldn't check in subtrees that are threaded. :)
Hope it helps future readers.