Bridges in an Undirected Graph - graph
A bridge can only exist between two articulation points or between an articulation point and a node with degree 1.
This is just an observation because if a vertex is articulation point then simply disconnecting from that node will give us bridges only.
Please tell me if this is true or false.
/*A sample file should contain edges as follow
1,2
2,3
4,5
5,3
Output will give the set of bridge nodes
*/
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct graph
{
int node;
struct graph *next;
}graph;
void init(int group[],int index[],graph *g[]);
void create_graph(graph *g[],int node1,int node2,int group[],int index[],int max_nodes);
int max(int a,int b);
int min(int a,int b);
void display(graph *g[],int group[],int max_nodes);
int query(graph *g[],int group[],int max_nodes,int first,int second);
void delete_node(graph *g[],int node1,int node2,int group[],int index[],int max_nodes);
int team=0;
int main()
{
char filename[50],ch;
int nodes[MAX][2],temp=0,node1,node2,group[MAX],index[MAX],max_nodes=0,i;
FILE *fp;
graph *g[MAX],*p;
init(group,index,g);
printf("Enter the filename - ");
scanf("%s",filename);
fp=fopen(filename,"r");
if(fp==NULL)
{
printf("File does not exist");
exit(1);
}
while(1)
{
ch=fgetc(fp);
if(isdigit(ch))
temp=temp*10+(ch-48);
else
{
if(ch!=','&&ch!='\n'&&ch!=EOF)
exit(1);
if(ch==',')
node1=temp;
else
{
node2=temp;
if(node1>max_nodes)
max_nodes=node1;
if(node2>max_nodes)
max_nodes=node2;
if(node1!=node2&&node1>0&&node2>0)
create_graph(g,node1,node2,group,index,max_nodes);
}
temp=0;
}
if(ch==EOF)
{
break;
}
}
display(g,group,max_nodes);
temp=0;
fclose(fp);
fp=fopen(filename,"r");
printf("Set of bridges existing - \n\n");
while(1)
{
ch=fgetc(fp);
if(isdigit(ch))
temp=temp*10+(ch-48);
else
{
if(ch!=','&&ch!='\n'&&ch!=EOF)
exit(1);
if(ch==',')
node1=temp;
else
{
node2=temp;
if(node1>max_nodes)
max_nodes=node1;
if(node2>max_nodes)
max_nodes=node2;
if(node1!=node2&&node1>0&&node2>0)
delete_node(g,node1,node2,group,index,max_nodes);
}
temp=0;
}
if(ch==EOF)
{
break;
}
}
return 0;
}
void init(int group[],int index[],graph *g[])
{
int i;
graph *p=NULL;
for(i=0;i<MAX;i++)
{
group[i]=index[i]=0;
g[i]=(graph *)malloc(sizeof(graph));
g[i]->node=0;
g[i]->next=NULL;
}
}
void create_graph(graph *g[],int node1,int node2,int group[],int index[],int max_nodes)
{
int temp_index,other_index,i,minimum;
int stack[MAX],stack_index=0;
graph *p;
p=g[node1];
if(p->next)
{
p=p->next;
while(p)
{
if(p->node==node2)
return;
p=p->next;
}
}
if(g[node1]->node<g[node2]->node)
{
temp_index=node1;
other_index=node2;
}
else
{
temp_index=node2;
other_index=node1;
}
p=g[temp_index];
p->node=p->node+1;
while(p->next!=NULL)
p=p->next;
p->next=(graph *)malloc(sizeof(graph));
p=p->next;
p->node=other_index;
p->next=NULL;
p=g[other_index];
p->node=p->node+1;
while(p->next)
p=p->next;
p->next=(graph *)malloc(sizeof(graph));
p=p->next;
p->node=temp_index;
p->next=NULL;
if(group[temp_index]==group[other_index]&&group[temp_index]==0)
{
{
team++;
group[temp_index]=group[other_index]=team;
}
}
else
{
if(group[temp_index]==0)
{
group[temp_index]=group[other_index];
}
{
minimum=min(group[temp_index],group[other_index]);
group[temp_index]=max(group[temp_index],group[other_index]);
for(i=1;i<=max_nodes;i++)
{
if(group[i]==minimum)
group[i]=max(group[temp_index],group[other_index]);
}
}
}
}
int max(int a,int b)
{
if(a>b)
return a;
return b;
}
int min(int a,int b)
{
if(a<b)
return a;
return b;
}
void display(graph *g[],int group[],int max_nodes)
{
int i;
graph *p;
printf("Graph\n");
printf("Id\tGrp\tNodes\n");
for(i=1;i<=max_nodes;i++)
{
printf("%d\t%d\t%d",i,group[i],g[i]->node);
p=g[i]->next;
while(p)
{
printf(" %d",p->node);
p=p->next;
}
printf("\n");
}
printf("\n\n");
}
int query(graph *g[],int group[],int max_nodes,int first,int second)
{
if(group[first]==group[second])
return 1;
else
return 0;
}
void delete_node(graph *g[],int node1,int node2,int group[],int index[],int max_nodes)
{
graph *p=NULL;
int i,temp,stack_index=0,stack[MAX];
p=g[node1];
while(p->next->node!=node2&&p->next)
p=p->next;
if(p->next)
{
p->next=p->next->next;
g[node1]->node=g[node1]->node-1;
}
p=g[node2];
while(p->next->node!=node1&&p->next)
p=p->next;
if(p->next)
{
p->next=p->next->next;
g[node2]->node=g[node2]->node-1;
}
team++;
group[node2]=team;
stack_index=0;
temp=node2;
p=g[temp]->next;
while(p)
{
stack[stack_index++]=p->node;
p=p->next;
}
for(i=0;i<stack_index;i++)
{
if(group[stack[i]]!=team)
{
group[stack[i]]=team;
p=g[stack[i]]->next;
while(p)
{
stack[stack_index++]=p->node;
p=p->next;
}
}
}
if(query(g,group,max_nodes,node1,node2)==0)
printf("%d %d\n",node1,node2);
create_graph(g,node1,node2,group,index,max_nodes);
}
In an undirected graph, a bridge can only exist between two articulation points. That goes straight from the definitions:
Bridge is an edge, such that removing it from the graph increases the number of connected components.
If you remove any of its endpoints, you therefore increase the number of connected components as well, and that's exactly the definition of articulation point.
I'm not sure what you mean with the part or between an articulation point and a node with out-degree 0. What would out-degree mean in an undirected graph?
Here are nice slides on Tarjan's algorithm, including its usage for detecting bridges and articulation points in graphs.
"The key issue is determining how the reachability relation impacts whether
vertex v is an articulation vertex. There are three cases:
• Root cut-nodes – If the root of the DFS tree has two or more children, it must
be an articulation vertex. No edges from the subtree of the second child can
possibly connect to the subtree of the first child.
• Bridge cut-nodes – If the earliest reachable vertex from v is v, then deleting
the single edge (parent[v], v) disconnects the graph. Clearly parent[v] must
be an articulation vertex, since it cuts v from the graph. Vertex v is also an
articulation vertex unless it is a leaf of the DFS tree. For any leaf, nothing
falls off when you cut it.
• Parent cut-nodes – If the earliest reachable vertex from v is the parent of v,
then deleting the parent must sever v from the tree unless the parent is the
root." - The algorithm design manual by Steve Skiena
Related
CGAL - 2D Delaunay triangulation - remove is not removing - Part 2
This question is continuing of the question CGAL - 2D Delaunay triangulation - remove is not removing Trying to solve the problem I decide to use for deletion the point returned on cdt.locate() so there will be not reason for the point do not be removed: //---TYPEDEFS typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Triangulation_vertex_base_2<K> Vb; typedef CGAL::Constrained_triangulation_face_base_2<K> Fb; typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS; typedef CGAL::Exact_predicates_tag Itag; typedef CGAL::Constrained_Delaunay_triangulation_2<K,TDS,Itag> CDT; typedef CDT::Point Point; typedef CDT::Vertex_handle Vertex_handle; typedef CDT::Vertex_circulator Vertex_circulator; typedef CDT::Face_handle Face_handle; ... int RemovePontosDesabilitados(CDT& cdt, tysetPonto3D& SetPonDesabilitados) { for (auto& RPonto : SetPonDesabilitados) { Point PonRemover(RPonto.x, RPonto.y); auto Face(cdt.locate(PonRemover)); if (Face != NULL) { int C(0); bool Achou(false); while (C < 3 && !Achou) { if((fabs(Face->vertex(C)->point().x()) - RPonto.x) < 1e-5 && (fabs(Face->vertex(C)->point().y()) - RPonto.y) < 1e-5) { Achou = true; } else { C++; } } if (Achou) { Point PonRemover(Face->vertex(C)->point().x(), Face->vertex(C)->point().y()); auto Tam = cdt.number_of_vertices(); auto PonIns = cdt.insert(PonRemover); Tam = cdt.number_of_vertices(); cdt.remove(PonIns); Tam = cdt.number_of_vertices(); } } } return 1; } But on cdt.insert(PonRemover) the point is inserted (See that this point is exactly the same point found in cdt.locate(PonRemover)) and on cdt.remove(PonIns) an exception is raised and the program finished. Why is this exception being raised? Thank you
Getting stuck in a loop, does local variable not visible to other workitems in a work group?
I am trying to use a local variable to syncronise among all the work-items in a work-group. However else part on conditional check always fails. Value of d[0] for other work-items does not equals to zero. Why local variable is not visible in the work-group? I am using AMD APU A12-9800 __kernel void test(__global int *input_vector,__global atomic_int *mem_flag) { local int d[32]; if(get_local_id(0)==0) { d[0] = 100; } barrier(CLK_GLOBAL_MEM_FENCE| CLK_LOCAL_MEM_FENCE); while(1) { if(get_local_id(0) == 0) { d[0] = 0; break; } else { if(d[0] == 0) break; } } }
as suggested by #alexg I added the barrier along with else condition removed and it worked. Here is the full code __kernel void test(__global int *input_vector,__global atomic_int *mem_flag) { local int d[32]; if(get_local_id(0)==0) { d[0] = 100; } barrier(CLK_GLOBAL_MEM_FENCE| CLK_LOCAL_MEM_FENCE); while(1) { mem_fence(CLK_GLOBAL_MEM_FENCE| CLK_LOCAL_MEM_FENCE); if(d[0] == 0) break; if(get_local_id(0) == 0) { d[0] = 0; } } }
Calculating the standard deviation of a linkedlist elements
I wanted to calculate the standard deviation of a inked list elements,so I wrote a function to calculate both the average and the sum and then claculate the standard deviation by the formula , but I am getting error " 0xC0000005: Access violation reading location 0x00000000."at the line 46 , sd += ((first->info)-average)*((first->info-average); Why this problem occurs and is there any way to get rid of it ? My code is as follows : class Node { public: int info; Node* next; int value; }; class List:public Node { Node *first,*last; public: List() { first=NULL; last=NULL; } void create(); void insert(); void delet(); void display(); void search(); void sum(); void sd(); }; void List::sd() { system("cls"); cout<<"The Linked List Operations Program"; cout<<"\n==========================================================="<<endl; Node *temp=first; int sd = 0; int length=0; while(temp!=NULL) { length++; temp=temp->next; } int sum = 0; while (first != NULL) { sum += first->info; first = first->next; } int average; average = (sum/length); sd += ((first->info)-average)*((first->info-average); first=first->next; cout<<average; cout<<"The standard diviation is " <<sqrt(sd)/10 ; cin.get(); cin.get(); } int main() { system("cls"); int m; List l; Node *first; int ch; l.sd(); return 0 ; } void List::create() { system("cls"); cout<<"The Linked List Operations Program"; cout<<"\n==========================================================="<<endl; Node *temp; temp=new Node; int n; cout<<"\nEnter an element to create the first node of the linkedlist:"; cin>>n; temp->info=n; temp->next=NULL; if(first==NULL) { first=temp; last=first; } else { last->next=temp; last=temp; } } void List::insert() { system("cls"); cout<<"The Linked List Operations Program"; cout<<"\n==========================================================="<<endl; Node *prev,*cur; prev=NULL; cur=first; int count=1,pos,ch,n; Node *temp=new Node; cout<<endl<<"ADDED"; system("cls"); temp->info=rand(); temp->next=NULL; last->next=temp; last=temp; }
Tree returning the maximum value
50 / \ 30 70 (( which should return 50+70=120 )) int MyFunction(struct node *root){ struct node *ptr=root; int leftsum=0; int rightsum=0; if(ptr==NULL){ return; } else{ MyFunction(ptr->left); leftsum=leftsum+ptr->key; MyFunctipn(ptr->right); rightsum=rightsum+ptr->key; return (root->key+max(leftsum,rightsum)); } } for that, I've written this code. Maybe it is wrong so please help me as I'm new in this field. I want to write a recursive code such a way that it compares two leaf node(left and right) and returns the maximum to the parent nood.
The recursive function should look something like this: int getMaxPath(Node* root){ // base case, We traveled beyond a leaf if(root == NULL){ // 0 doesn't contribute anything to our answer return 0; } // get the max current nodes left and right children int lsum = getMaxPath(root->left); int rsum = getMaxPath(root->right); // return sum of current node value and the maximum from two paths starting with its two child nodes return root->value + std::max(lsum,rsum); } Full code: #include <iostream> struct Node{ int value; Node* left; Node* right; Node(int val){ value = val; left = NULL; right = NULL; } }; // make a tree and return a pointer to it's root Node* buildTree1(){ /* Build tree like this: 50 / \ 30 70 */ Node* root= new Node(50); root->left = new Node(30); root->right = new Node(70); } int getMaxPath(Node* root){ if(root == NULL){ // 0 doesn't contribute anything to our answer return 0; } int lsum = getMaxPath(root->left); int rsum = getMaxPath(root->right); return root->value + std::max(lsum,rsum); } int main() { using namespace std; Node* root = buildTree1(); int ans = getMaxPath(root); cout<< ans <<endl; return 0; }
int Sum(struct node *root) { if(root->left == NULL && root->right== NULL) return root->key; int lvalue,rvalue; lvalue=Sum(root->left); rvalue=Sum(root->right); return root->key+max(lvalue,rvalue); } int max(int r,int j) { if(r>j) return r; else return j; }
Finding the cycle in an undirected graph using BFS
I want to find first cycle in an undirected graph using BFS only(NOT DFS). All sources solved this problem with DFS but I have to find it using BFS. How can I find it? Thanks in advance!
Here below you will find the code to traverse a graph using BFS and find its cycles. #include <stdio.h> #include <queue> using namespace std; int nodes, edges, src; int graph[100][100], color[100], prev[100]; const int WHITE = 0; const int GRAY = 1; const int BLACK = 2; void print(int); int main() { printf("Nodes, edges, source? "); scanf("%d %d %d ", &nodes, &edges, &src); for(int i = 1; i <= edges; i++) { printf("Edge %d: ", i); int x, y; scanf("%d %d", &x, &y); graph[x][y] = 1; } //run BFS queue<int> q; //create a queue q.push(src); //1. put root node on the queue do{ int u = q.front(); //2. pull a node from the beginning of the queue q.pop(); printf("%d ", u); //print the node for(int i = 1; i <= nodes; i++) { //4. get all the adjacent nodes if((graph[u][i] == 1) //if an edge exists between these two nodes, && (color[i] == WHITE)) { //and this adjacent node is still WHITE, q.push(i); //4. push this node into the queue color[i] = GRAY; //color this adjacent node with GRAY } } color[u] = BLACK; //color the current node black to mark it as dequeued } while(!q.empty()); //5. if the queue is empty, then all the nodes havebeen visited //find and print cycle from source for(int i = 1; i <= nodes; i++) { if(graph[i][src] == 1) { print(i); printf("%d\n\n", src); } } return 0; } void print(int node) { if(node == 0) return; print(prev[node]); printf("%d -> ", node); } Also I recommend you to take a look at this brief and useful guide.