Skip to content

Commit 75202cc

Browse files
committed
sept21: finally finished G - Graduation
1 parent df990cc commit 75202cc

File tree

4 files changed

+724
-18
lines changed

4 files changed

+724
-18
lines changed

2019/sept21/g-graduation.cpp

Lines changed: 192 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,206 @@
11
#include <iostream>
22
#include <string>
33
#include <vector>
4+
#include <stack>
5+
#include <queue>
6+
#include <set>
47
using namespace std;
58

6-
/*
7-
g++ -std=c++11 k-kernel.cpp -o k
8-
1 to 2*10^5 strings
9-
*/
9+
void debug() { printf("DEBUG\n"); }
10+
void debug(int i) { printf("DEBUG: %d\n", i); }
1011

11-
int main() {
12+
class Graph {
13+
public:
14+
Graph(int n) {
15+
if(n <= 0)
16+
throw std::invalid_argument( "n must be positive" );
17+
size = n;
18+
edges = new bool*[size];
19+
for(int i = 0; i < n; i++) {
20+
edges[i] = new bool[size];
21+
for(int j = 0; j < n; j++)
22+
edges[i][j] = false;
23+
}
24+
}
25+
26+
/* destructor */
27+
~Graph() {
28+
internal_destructor();
29+
}
1230

13-
int c, n, t1, t2;
14-
cin >> c;
15-
int a[c];
16-
for(int i = 0; i < c; i++) {
17-
cin >> n;
18-
n += 1;
19-
if(n > 3) {
20-
a[i] = 1 + (2 * (((n - (n % 3)) - 3) / 3)) + (n % 3);
21-
} else {
22-
a[i] = 0;
31+
/* copy constructor */
32+
Graph(const Graph &g) {
33+
internal_copy(g);
34+
}
35+
36+
/* assignment operator */
37+
Graph& operator=(const Graph &g) {
38+
if(this == &g) return *this;
39+
internal_destructor();
40+
internal_copy(g);
41+
return *this;
42+
}
43+
44+
int get_size() { return size; }
45+
46+
/* returns true iff edge has been added successfully */
47+
bool add_edge(int from, int to) {
48+
if(edges[from][to])
49+
return false;
50+
else {
51+
edges[from][to] = true;
52+
return true;
2353
}
2454
}
2555

26-
for(int i = 0; i < c; i++)
27-
cout << a[i] << endl;
56+
/* returns true iff edge has been removed successfully */
57+
bool rem_edge(int from, int to) {
58+
if(edges[from][to]) {
59+
edges[from][to] = false;
60+
return true;
61+
} else
62+
return false;
63+
}
64+
65+
set<int> outgoing_edges(int vertex) {
66+
if(vertex < 0 || vertex >= size)
67+
throw std::invalid_argument( "vertex is out of bounds" );
68+
set<int> og;
69+
for(int i = 0; i < size; i++)
70+
if(edges[vertex][i])
71+
og.insert(i);
72+
return og;
73+
}
2874

29-
return 0;
75+
bool has_outgoing(int vertex) {
76+
if(vertex < 0 || vertex >= size)
77+
throw std::invalid_argument( "vertex is out of bounds" );
78+
for(int i = 0; i < size; i++)
79+
if(edges[vertex][i])
80+
return true;
81+
return false;
82+
}
83+
84+
set<int> incoming_edges(int vertex) {
85+
if(vertex < 0 || vertex >= size)
86+
throw std::invalid_argument( "vertex is out of bounds" );
87+
set<int> ic;
88+
for(int i = 0; i < size; i++)
89+
if(edges[i][vertex])
90+
ic.insert(i);
91+
return ic;
92+
}
93+
94+
bool has_incoming(int vertex) {
95+
if(vertex < 0 || vertex >= size)
96+
throw std::invalid_argument( "vertex is out of bounds" );
97+
for(int i = 0; i < size; i++)
98+
if(edges[i][vertex])
99+
return true;
100+
return false;
101+
}
102+
103+
private:
104+
int size;
105+
bool **edges;
106+
107+
void internal_destructor() {
108+
for(int i = 0; i < size; i++) {
109+
delete[] edges[i];
110+
}
111+
delete[] edges;
112+
}
113+
114+
void internal_copy(const Graph &g) {
115+
size = g.size;
116+
edges = new bool*[size];
117+
for(int i = 0; i < size; i++) {
118+
edges[i] = new bool[size];
119+
for(int j = 0; j < size; j++) {
120+
edges[i][j] = g.edges[i][j];
121+
}
122+
}
123+
}
124+
};
125+
126+
void top_sort_school(Graph &g, int k) {
127+
// noedge - vtx has no incoming edges
128+
// nonoedge - vtx has no incoming or outgoing edges
129+
// we want to prioritize taking courses that have prereqs.
130+
queue<int> noedge, nonoedge, tmpnoedge, tmpnonoedge;
131+
vector<int> v;
132+
int l, m, acc; acc = 0;
133+
set<int> nbrs;
134+
135+
for(int i = 0; i < g.get_size(); i++) {
136+
if(!g.has_incoming(i)) {
137+
if(!g.has_outgoing(i)) nonoedge.push(i);
138+
else noedge.push(i);
139+
}
140+
}
141+
142+
while(!noedge.empty() || !nonoedge.empty()) {
143+
acc++;
144+
m = min(k, (int) (noedge.size() + nonoedge.size()));
145+
//cout << "stack sz: " << m << endl;
146+
for(int i = 0; i < m; i++) {
147+
if(!noedge.empty()) {
148+
l = noedge.front(); noedge.pop();
149+
} else {
150+
l = nonoedge.front(); nonoedge.pop();
151+
}
152+
//cout << acc << ": " << l << endl;
153+
154+
// remove all edges outgoing from k
155+
for(int j : g.outgoing_edges(l)) {
156+
g.rem_edge(l, j);
157+
if(!g.has_incoming(j)) {
158+
if(!g.has_outgoing(j)) tmpnonoedge.push(j);
159+
else tmpnoedge.push(j);
160+
}
161+
}
162+
}
163+
while(!tmpnoedge.empty()) {
164+
noedge.push(tmpnoedge.front()); tmpnoedge.pop();
165+
}
166+
while(!tmpnonoedge.empty()) {
167+
nonoedge.push(tmpnonoedge.front()); tmpnonoedge.pop();
168+
}
169+
}
170+
171+
cout << acc << endl;
30172
}
31173

174+
/*
175+
Solution using two queues instead of stacks that still does not work
176+
177+
g++ -std=c++11 g-graduation.cpp -o k
178+
179+
4 2
180+
3 3 4 0
181+
182+
3 3
183+
0 1 2
184+
185+
10 3
186+
9 9 9 9 10 10 10 10 11 11 0
187+
188+
6 3
189+
2 0 2 2 0 0
32190
191+
9 3
192+
2 0 2 2 0 0 6 6 6
193+
*/
194+
int main() {
195+
int n, k, a;
196+
cin >> n >> k;
197+
Graph g = Graph(n);
198+
for(int i = 0; i < n; i++) {
199+
cin >> a;
200+
if(a)
201+
g.add_edge(i, a - 1);
202+
}
203+
204+
top_sort_school(g, k);
205+
return 0;
206+
}

0 commit comments

Comments
 (0)