Skip to content

Commit 8bf4cc8

Browse files
committed
topsort cycle check added
1 parent 4004eea commit 8bf4cc8

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
2+
/**
3+
4+
Cycle check (Directed Graph)
5+
===========
6+
7+
Here the idea is to use TOP SORT .
8+
After top sort , let the topological order be like this
9+
10+
A -> B -> C -> D
11+
12+
if there is an edge from A to D (i.e from lower position to higher position in topological order) , it won't create a cycle .
13+
BUT if there is an edge from D to A (i.e from higher position to lower position in topological order) , it WILL create a cycle .
14+
15+
This is the core idea behind cycle checking here .
16+
17+
Idea
18+
====
19+
20+
For each edge we check if it connects from higher position to lower position in topological order .
21+
If we find one like this , there is a cycle
22+
23+
Complexity : O(V+E)
24+
25+
**/
26+
27+
/**Which of the favors of your Lord will you deny ?**/
28+
29+
#include<bits/stdc++.h>
30+
using namespace std;
31+
32+
#define LL long long
33+
#define PII pair<int,int>
34+
#define PLL pair<LL,LL>
35+
#define MP make_pair
36+
#define F first
37+
#define S second
38+
#define INF INT_MAX
39+
40+
#define ALL(x) (x).begin(), (x).end()
41+
#define DBG(x) cerr << __LINE__ << " says: " << #x << " = " << (x) << endl
42+
43+
#include <ext/pb_ds/assoc_container.hpp>
44+
#include <ext/pb_ds/tree_policy.hpp>
45+
using namespace __gnu_pbds;
46+
47+
template<class TIn>
48+
using indexed_set = tree<
49+
TIn, null_type, less<TIn>,
50+
rb_tree_tag, tree_order_statistics_node_update>;
51+
52+
/**
53+
54+
PBDS
55+
-------------------------------------------------
56+
1) insert(value)
57+
2) erase(value)
58+
3) order_of_key(value) // 0 based indexing
59+
4) *find_by_order(position) // 0 based indexing
60+
61+
**/
62+
63+
inline void optimizeIO()
64+
{
65+
ios_base::sync_with_stdio(false);
66+
cin.tie(NULL);
67+
}
68+
69+
const int nmax = 2e5+7;
70+
const LL LINF = 1e17;
71+
72+
string to_str(LL x)
73+
{
74+
stringstream ss;
75+
ss<<x;
76+
return ss.str();
77+
}
78+
79+
vector<vector<int>>adj;
80+
81+
vector<bool>vis;
82+
vector<int>stk;
83+
vector<int>pos;
84+
85+
void dfs(int u)
86+
{
87+
vis[u] = true;
88+
89+
for(int v:adj[u])
90+
{
91+
if(vis[v])
92+
continue;
93+
94+
dfs(v);
95+
}
96+
97+
stk.push_back(u);
98+
}
99+
100+
bool hasCycle(int n,const vector<PII> &dir_edges)
101+
{
102+
fill(ALL(vis),0);
103+
104+
for(int i=1; i<=n; i++)
105+
if(!vis[i])
106+
dfs(i);
107+
108+
int cnt = 0;
109+
110+
while(!stk.empty())
111+
{
112+
int now = stk.back();
113+
stk.pop_back();
114+
pos[now] = ++cnt;
115+
}
116+
117+
for(auto e:dir_edges)
118+
{
119+
int u = e.F , v = e.S;
120+
121+
if(pos[u]>pos[v]) /** edge is from RIGHT to LEFT in the topological order and that's why creating cycle **/
122+
return true;
123+
}
124+
125+
return false;
126+
}
127+
128+
void RESIZE(int n)
129+
{
130+
adj = vector<vector<int>>(n);
131+
vis = vector<bool>(n);
132+
pos = vector<int>(n);
133+
stk.clear();
134+
}
135+
136+
int main()
137+
{
138+
optimizeIO();
139+
140+
int n,m;
141+
cin>>n>>m;
142+
143+
RESIZE(n+1);
144+
145+
vector<PII>dir_ed;
146+
147+
for(int i=0;i<m;i++)
148+
{
149+
int a,b;
150+
cin>>a>>b;
151+
152+
adj[a].push_back(b);
153+
dir_ed.push_back({a,b});
154+
}
155+
156+
bool cycle = hasCycle(n,dir_ed);
157+
158+
if(cycle) cout<<"Has Cycle"<<endl;
159+
else cout<<"No Cycle"<<endl;
160+
161+
return 0;
162+
}
163+
164+

0 commit comments

Comments
 (0)