Skip to content

Commit 28d2f7a

Browse files
authored
Merge pull request #75 from Nitishg1223/master
Finding of Articulation Points in a Graph
2 parents 493c17b + 9bed335 commit 28d2f7a

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include <iostream>
2+
#include<bits/stdc++.h>
3+
using namespace std;
4+
#define f first
5+
#define ll long long int
6+
#define REP(i,k,n) for(int i=k;i<n;i++)
7+
#define s second
8+
#define pb push_back
9+
#define vi vector<int>
10+
#define mp make_pair
11+
#define pii pair<int,int>
12+
#define fast ios::sync_with_stdio(false);cin.tie(0);
13+
#define maxl 100005
14+
//So ultimately it all converges down to finding a back edge for every vertex.
15+
//So, for that apply a DFS and record the discovery time of every vertex and
16+
// maintain for every vertex the earliest discovered vertex that can be reached from any of the vertices in the subtree rooted at .
17+
//If a vertex is having a child such that the earliest discovered vertex that can be reached from the vertices in the subtree rooted at has a discovery time greater than or equal to , then does not have a back edge, and thus will be an articulation point.
18+
19+
//So, till now the algorithm says that if all children of a vertex are having a back edge, then is not an articulation point. But what will happen when is root of the tree, as root does not have any ancestors.
20+
// Well, it is very easy to check if the root is an articulation point or not.
21+
//If root has more than one child than it is an articulation point otherwise it is not.
22+
// Now how does that help?? Suppose root has two children, and .
23+
//If there had been an edge between vertices in the subtree rooted at and those of the subtree rooted at , then they would have been a part of the same subtree.
24+
//vertex, count children. If currently visited vertex u is root (parent[u] is NIL) and has more than two children, print it.
25+
//How to handle second case? The second case is trickier. We maintain an array disc[] to store discovery time of vertices. For every node u, we need to find out the earliest visited vertex (the vertex with minimum discovery time) that can be reached from subtree rooted with u. So we maintain an additional array low[] which is defined as follows.
26+
27+
28+
bool vis[maxl];
29+
bool ap[maxl];
30+
vi v[maxl];
31+
int parent[maxl];
32+
int disc[maxl]; //discovery time it will store the time they will be find in dfs tree (it will be unique)
33+
int low[maxl]; //it will hold lowest(upppermost) ancestor one can go by using only one back edge(multiple normal edges) in dfs tree
34+
int timer=0;
35+
void dfs(int idx)
36+
{
37+
vis[vert]=true;
38+
disc[vert]=low[vert]=++timer;
39+
int cntchild=0;
40+
for(int i=0;i<v[vert].size();i++)
41+
{
42+
int child=v[vert][i];
43+
if(vis[child]==false)
44+
{
45+
cntchild++;
46+
parent[child]=vert;
47+
dfs(child);
48+
low[vert]=min(low[vert],low[child]);
49+
if(cntchild>1&&parent[vert]==-1)
50+
ap[vert]=true;
51+
if(parent[vert]!=-1&&low[child]>=disc[vert])
52+
ap[vert]=true;
53+
}
54+
else
55+
{
56+
if(parent[vert]!=-1)
57+
low[vert]=min(low[vert],disc[child]);
58+
}
59+
}
60+
61+
}
62+
void calap(int n)
63+
{
64+
REP(i,0,n+1)
65+
{
66+
ap[i]=false;
67+
vis[i]=false;
68+
parent[i]=-1;
69+
disc[i]=0;
70+
low[i]=INT_MAX;
71+
72+
}
73+
REP(i,1,n+1)
74+
{
75+
if(!vis[i])
76+
dfs(i);
77+
}
78+
int cnt=0;
79+
REP(i,1,n+1)
80+
if(ap[i])
81+
cout<<i<<" ";
82+
83+
84+
}
85+
int main() {
86+
// your code goes here
87+
int n,m;
88+
cin>>n>>m;
89+
90+
REP(i,0,m)
91+
{
92+
int x,y;
93+
cin>>x>>y;
94+
v[x].pb(y);
95+
v[y].pb(x);
96+
}
97+
calap(n);
98+
99+
return 0;
100+
}

0 commit comments

Comments
 (0)