connected components of triangle faces in a mesh - graph

I have a list of vertices and faces which index the vertex:
For example the list of vertices are (x,y,z) :
0 1 0
1 1 1
2 0 1
3 0 0
1 1 2
...
...
...
Faces that index the vertex:
0 1 2
2 3 4
4 0 1
...
...
...
With the list of faces I need to group them up for those that faces are connected to each other. For the first 3 faces I know that they are connected to each other as they have common index. How do I implement an algorithm to do this? thanks.
I use the method from this link using depth first search to visit all the node but gets a segmentation fault inside the class
https://www.geeksforgeeks.org/depth-first-search-or-dfs-for-a-graph/
#include <bits/stdc++.h>
using namespace std;
class Graph {
// A function used by DFS
void DFSUtil(int v);
public:
int count;
map<int, bool> visited;
map<int, list<int> > adj;
// function to add an edge to graph
void addEdge(int v, int w);
// prints DFS traversal of the complete graph
void DFS();
};
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w); // Add w to v’s list.
}
void Graph::DFSUtil(int v)
{
// Mark the current node as visited and print it
visited[v] = true;
cout << v << " ";
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i])
DFSUtil(*i);
}
// The function to do DFS traversal. It uses recursive
// DFSUtil()
void Graph::DFS()
{
count = 0;
// Call the recursive helper function to print DFS
// traversal starting from all vertices one by one
for (auto i : adj)
if (visited[i.first] == false)
{
DFSUtil(i.first);
count++;
}
}
int main()
{
// Create a graph given in the above diagram
Graph g;
for face in faces :
{
g.addEdge(face[0], face[1]);
g.addEdge(face[0], face[2]);
g.addEdge(face[1], face[0]);
g.addEdge(face[1], face[2]);
g.addEdge(face[2], face[0]);
g.addEdge(face[2], face[1]);
}
cout << "Following is Depth First Traversal \n";
// Function call
g.DFS();
cout << "number of connected components = " << g.count << "\n";
return 0;
}

Related

Why Complete LinkedList Reversed?

For Input 1->2->2->4->5->6->7->8
My output is 8 7 6 5 4 2 2 1 but I don't know why?
LINK OF PROBLEM IS BELOW :
https://practice.geeksforgeeks.org/problems/reverse-a-linked-list-in-groups-of-given-size/1
Reverse a Linked List in groups of given size.
Given a linked list of size N. The task is to reverse every k nodes (where k is an input to the function) in the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should be considered as a group and must be reversed (See Example 2 for clarification).
Example 1:
Input:
LinkedList: 1->2->2->4->5->6->7->8
K = 4
Output: 4 2 2 1 8 7 6 5
Explanation:
The first 4 elements 1,2,2,4 are reversed first
and then the next 4 elements 5,6,7,8. Hence, the
resultant linked list is 4->2->2->1->8->7->6->5.
Example 2:
Input:
LinkedList: 1->2->3->4->5
K = 3
Output: 3 2 1 5 4
Explanation:
The first 3 elements are 1,2,3 are reversed
first and then elements 4,5 are reversed.Hence,
the resultant linked list is 3->2->1->5->4.
Your Task:
You don't need to read input or print anything. Your task is to complete the function reverse() which should reverse the linked list in group of size k and return the head of the modified linked list.
Expected Time Complexity : O(N)
Expected Auxilliary Space : O(1)
Constraints:
1 <= N <= 104
1 <= k <= N
MY CODE BELOW:
//{ Driver Code Starts
#include<bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node* next;
node(int x){
data = x;
next = NULL;
}
};
/* Function to print linked list */
void printList(struct node *node)
{
while (node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
printf("\n");
}
// } Driver Code Ends
/*
Reverse a linked list
The input list will have at least one element
Return the node which points to the head of the new LinkedList
Node is defined as
struct node
{
int data;
struct node* next;
node(int x){
data = x;
next = NULL;
}
}*head;
*/
class Solution
{
node* reverseHelper(node* head){
node* pre = NULL;
node* curr = head;
while(curr!=NULL){
node* nextTocurr = curr->next;
curr->next = pre;
pre = curr;
curr = nextTocurr;
}
return pre;
}
public:
struct node *reverse (struct node *head, int k)
{
// Complete this method
if(head==NULL|| head->next==NULL){
return head;
}
int count = 0;
node* tail = head;
while(count<k || tail->next!=NULL){
tail = tail->next;
count++;
}
node* head2 = tail->next;
tail->next = NULL;
node* ans = reverseHelper(head);
head->next = reverse(head2,k);
return ans;
}
};
//{ Driver Code Starts.
/* Drier program to test above function*/
int main(void)
{
int t;
cin>>t;
while(t--)
{
struct node* head = NULL;
struct node* temp = NULL;
int n;
cin >> n;
for(int i=0 ; i<n ; i++)
{
int value;
cin >> value;
if(i == 0)
{
head = new node(value);
temp = head;
}
else
{
temp->next = new node(value);
temp = temp->next;
}
}
int k;
cin>>k;
Solution ob;
head = ob.reverse(head, k);
printList(head);
}
return(0);
}
// } Driver Code Ends
The problem is in this loop:
int count = 0;
while(count<k || tail->next!=NULL){
It has two issues:
The loop will continue until the end of the list because the second condition will be true until that end is reached. The logical OR (||) should be a logical AND (&&), because you want both conditions to be true, not just one.
When the previous point is corrected, the loop will still iterate one time too many, because the head node was already considered to be included in the "slice". Correct by initialising count=1.
With those two corrections your code will work as intended.

C Program to Search a Node in Binary Tree

this code is from binary search tree I don't know this code showing same output
I don't know where the problem is occurring I already tried to change the variables but it didn't work
What seems to be the problem? i already tried so many things but still not able to fix the errors.
#include <stdio.h>
#include <stdlib.h>
****// Basic struct of Tree****
struct node
{
int data;
struct node *left;
struct node *right;
};
****// Function to create a new Node****
struct node *createNode(int item)
{
struct node *newNode = malloc(sizeof(struct node));
newNode->left = NULL;
newNode->right = NULL;
newNode->data = item;
return newNode;
}
int search(struct node *root, int value)
{
if (root == NULL)
return 0;
if (root->data == value)
return 1;
if (root->data < value)
return search(root->right, value);
else
return search(root->left, value);
}
int main()
{
**// struct node *root = NULL;**
struct node *root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);
root->right->right = createNode(6);
root->left->right->left = createNode(7);
root->left->right->right = createNode(8);
root->right->right->left = createNode(9);
int item = 34;
// Function to find item in the tree
int found = search(root, item);
if (found)
printf("%d value is found in the tree", item);
else
printf("%d value not found", item);
return 0;
}
The problem is that your search function expects to get a binary search tree, but your main program created a binary tree that is not a binary search tree, but this:
1
/ \
2 3
/ \ \
4 5 6
/ \ /
7 8 9
And of course, a search for 34 will anyway return 0, as it does not occur anywhere in this tree. But even if you would search for let's say 8, it would return 0.
Your search code will not work with such a tree. If you would have made a binary search tree, like for instance this one:
6
/ \
2 7
/ \ \
1 4 9
/ \ /
3 5 8
...then it would work when calling search for any value in or not in the tree. For instance, this will print "5 value is found in the tree":
int main()
{
struct node *root = createNode(6);
root->left = createNode(2);
root->right = createNode(7);
root->left->left = createNode(1);
root->left->right = createNode(4);
root->right->right = createNode(9);
root->left->right->left = createNode(3);
root->left->right->right = createNode(5);
root->right->right->left = createNode(8);
int item = 5;
// Function to find item in the tree
int found = search(root, item);
if (found)
printf("%d value is found in the tree", item);
else
printf("%d value not found", item);
return 0;
}
This function is for binary search tree (BST).
int search(struct node *root, int value)
{
if (root == NULL)
return 0;
if (root->data == value)
return 1;
if (root->data < value)
return search(root->right, value);
else
return search(root->left, value);
}
As you need to a program to work on any binary tree.
You can change it to work on an any binary tree.
int search(struct node *root, int value)
{
if (root == NULL)
return 0;
if (root->data == value)
return 1;
return search(root->right, value) || search(root->left, value);
}

mother vertex using disjoint dataset in directed graph

I had the solution of classical Mother vertex problem using DSU (disjoint data set). I have used path compression.
i wanted to know if it is correct or not.I think time complexity O(E log(V)).
the solution proceeds as
initialise each vertex's parent as it self
as soon as a edge comes, try to join them. note that 1->2 can't be merged if 2 already has some other parent! like if graph is 1->2 , 3->4 , 2->4
here edges 1->2 merge as par[1] = par[2]= 1 and 3->4 merge as par[3]= par[4] =3.
when it comes to merge 2->4, we can't since par[4]!=4, aka, it has some other incoming edge, out of this group.
atlast, all the parent vertices are checked, if they are all equal then, mother vertexos present.
code is :
class dsu
{
public:
int cap;
vector<int> par;
dsu(int n)
{
cap = n;
par.resize(cap);
for(int i=0; i<cap; i++)
par[i] = i;
}
int get(int a)
{
while(a!= par[a])
{
par[a] = par[par[a]];
a = par[a];
}
return a;
}
void join(int a, int b)
{
a= get(a);
int pb= get(b);
if(pb!=b)
return ;
par[pb] = a;
}
};
int findMother(int n, vector<int> g[])
{
// Your code here
// do disjoint data set, if everyone;s parent is same woohla! i have found the mother vertex
dsu arr(n);
for(int i=0; i< n; i++)
{
for(auto a: g[i])
{
arr.join(i,a);}
}
int mother = arr.get(0);
for(int i=1; i<n; i++)
{
if(mother != arr.get(i))
return -1;
}
return mother;
}
after some research I have fount out that, it is correct. It can be used to find the mother vertex .

Can anyone spot what is wrong with that code?

I have been trying to solve a problem from coursera.
Problem description: Given an undirected graph with 𝑛 vertices and 𝑚 edges, check whether it is bipartite.
Input Format. A graph is given in the standard format.
Constraints. 1 ≤ 𝑛 ≤ 105, 0 ≤ 𝑚 ≤ 105.
Output Format. Output 1 if the graph is bipartite and 0 otherwise.
Input:
4 4
1 2
4 1
2 3
3 1
Output:
0
Input:
5 4
5 2
4 2
3 4
1 4
Output:
1
I came up with a solution in c++ that looks like
#include <bits/stdc++.h>
using namespace std;
#define vvi vector<vector<int>>
#define vi vector<int>
#define qi queue<int>
int bfs(vvi adj, int s, vi &disc, vi &dist)
{
disc[s] = 1; dist[s] = 0;
qi q;
q.push(s);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i: adj[u])
{
if(!disc[i])
{
disc[i] = 1;
q.push(i);
dist[i] = dist[u]+1;
}else if(dist[u]==dist[i])
{
return 0;
}
}
}
return 1;
}
bool isBipartite(vvi adj, vi &disc, vi &dist)
{
for(int i=0;i<adj.size();++i)
{
if(!disc[i])
{
if(!bfs(adj, i, disc, dist))
{
return 0;
}
}
}
return 1;
}
int main()
{
int n, m;
cin >> n >> m;
vvi adj(n);
for(int i=0;i<m;++i)
{
int x, y;
cin >> x >> y;
adj[x-1].push_back(y-1);
adj[y-1].push_back(x-1);
}
vi dist(n);
vi disc(n, 0);
cout << isBipartite(adj, disc, dist);
}
But this solution is generating wrong answer on test case 3. Can anyone figure out what I have missed in that code?
Thanks in advance. ♥
Your logic seems flawless, there is a possible cause of error: you don't pass adj parameter as a reference. This mean that for every call of bfs method the graph will be copied. If 3rd test case is an isolated graph (no edges) that would be bad. Sometimes runtime error and memory exceeded error are treated by the online judge as a non existent wrong answer.

Maximum no. of nodes reachable from a given source in a Graph

I have a directed graph in which each node has exactly one edge, to one other node. I have to find the node from which the maximum number of nodes can be reached.
I tried to do it using a dfs, and store the information in the array sum[] but I get segmentation faults.
The graph is represented as an adjacency List of pair< int, int >. First is the destination, and second is the weight. In this problem weight = 0.
My dfs implementation:
int sum[V]; // declared globally, initially set to 0
bool visited[V]; // declared globally, initially set to false
int dfs( int s ){
visited[s]= true;
int t= 0;
for( int i= 0; i< AdjList.size(); ++i ){
pii v= AdjList[s][i];
if( visited[v.first] )
return sum[v.first];
t+= 1 + dfs( v.first );
}
return sum[s]= t;
}
Inside main():
int maxi= -1; // maximum no. of nodes that can be reached
for( int i= 1; i<= V; ++i ){ // V is total no. of Vertices
int cc;
if( !visited[i] )
cc= g.dfs( i ) ;
if( cc > maxi ){
maxi= cc;
v= i;
}
}
And the graph is :
1 2 /* 1---->2 */
2 1 /* 2---->1 */
5 3 /* 5---->3 */
3 4 /* 3---->4 */
4 5 /* 4---->5 */
What is be the problem in my dfs implementation?
You exit your dfs when you find any node that was already reached, but I have the impresion that you should run through all adjectent nodes: in your dfs function change the if statement inside for loop:
instead:
if(visited[v.first] )
return sum[v.first];
t+= 1 + dfs( v.first );
if(!visited[v.first] ) {
t+= dfs( v.first );
}
and initialize t with 1 (not 0). This way you will find size of connected component. Because you are not interested in the node from which you started then you have to decrease the final result by one.
There is one more assumption that I made: your graph is undirected. If it's directed then if you are interested in just solving the problem (not about complexity) then just clear visited and sum array after you are done with single run of dfs in main function.
EDIT
One more error in your code. Change:
for( int i= 0; i< AdjList.size(); ++i ){
into:
for( int i= 0; i< AdjList[s].size(); ++i ){
You should be able to trace segfault by yourself. Use gdb it's really usefull tool.

Resources