forked from MountAim/Graph-Coding-Minutes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
54-GCD on Directed Path.cpp
115 lines (100 loc) · 2.89 KB
/
54-GCD on Directed Path.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include<bits/stdc++.h>
using namespace std;
#define INF 1000000009
vector<int>A,val,comp;
vector <vector<int>> v,rev_v,scc_v;
vector<bool>vis;
int components;
vector<set <int>> ss;
/**
* Push the vertices in the stack in the decreasing order
* of their finishing times.
*
* First DFS of the Kosaraju Algorithm
**/
void dfs_0(int curr,stack<int>&s)
{
vis[curr] = true;
for ( int i = 0; i < (int)v[curr].size(); i++ ) {
if ( vis[v[curr][i]] ) continue;
dfs_0(v[curr][i],s);
}
s.push(curr);
}
void dfs_1(int curr)
{
vis[curr] = true;
comp[curr] = components;
val[components] = __gcd(val[components], A[curr]);
for ( int i = 0; i < (int)rev_v[curr].size(); i++ ) {
if ( vis[rev_v[curr][i]] ) continue;
dfs_1(rev_v[curr][i]);
}
}
void dfs_2(int curr,stack<int>&s)
{
vis[curr] = true;
for ( int i = 0; i < (int)scc_v[curr].size(); i++ ) {
if ( vis[scc_v[curr][i]] ) continue;
dfs_2(scc_v[curr][i],s);
}
s.push(curr);
}
int solve(int n,vector<int> c, vector<vector<int>> edges){
v=rev_v=scc_v=vector<vector<int>>(n+1,vector<int>());
A=val=comp=vector<int>(n+1);
ss=vector<set<int>>(n+1,set<int>());
stack<int>s;
vis.assign(n+1,false);
components=0;
int x, y;
for ( int i = 1; i <= n; i++ ) {
A[i]=c[i-1];
}
for ( int i = 0; i < edges.size(); i++ ) {
x=edges[i][0],y=edges[i][1];
v[x].push_back(y);
rev_v[y].push_back(x);
}
for ( int i = 1; i <= n; i++ ) {
if ( !vis[i] ) dfs_0(i,s);
}
vis.assign(n+1,false);
components = 0;
while ( !s.empty() ) {
int curr = s.top();
s.pop();
if ( !vis[curr] ) {
components++;
dfs_1(curr);
}
}
//Create an scc condensed dag graph
//Number of vertices = components
//Edges -> scc[]
//Value on each node of this scc - val[i]
for ( int i = 0; i < edges.size(); i++ ) {
if ( comp[edges[i][0]] != comp[edges[i][1]] ) {
scc_v[comp[edges[i][0]]].push_back(comp[edges[i][1]]);
}
}
vis.assign(n+1,false);
//Perform a topological sort on this.
for ( int i = 1; i <= components; i++ ) {
if ( !vis[i] ) dfs_2(i,s);
}
int ans = INF;
while ( !s.empty() ) {
int curr = s.top();
s.pop();
ss[curr].insert(val[curr]);
ans = min(ans, val[curr]);
for ( set <int> :: iterator it = ss[curr].begin(); it != ss[curr].end(); it++ ) {
for ( int j = 0; j < (int)scc_v[curr].size(); j++ ) {
ss[scc_v[curr][j]].insert(__gcd(*it, val[scc_v[curr][j]]));
ans = min(ans, __gcd(*it, val[scc_v[curr][j]]));
}
}
}
return ans;
}