1
+ /*
2
+ Not fully sure why this solution passes haha
3
+
4
+ Find SCC's. Can be proved that if a node in scc A points to a node in scc B, then every
5
+ node in scc A points to every node in scc B (since otherwise A and B would be the same SCC)
6
+
7
+ Find a cycle in every SCC that visits every node once. The way I did this was a little questionable;
8
+ I found a path that visits every node once, then repeatedly while the last node in this path
9
+ did not connect to the first node, I moved the last node up in the path as much as possible in O(n) time.
10
+ I don't have a proof as to why this works
11
+
12
+ After you can just DFS to determine which SCC to go to next to maximize path length, and from every SCC
13
+ just follow the cycle to visit every node in that SCC once.
14
+ */
15
+
1
16
#include < bits/stdc++.h>
2
17
3
18
using namespace std ;
@@ -46,17 +61,14 @@ void tarjan(int u) {
46
61
}
47
62
48
63
if (dfsLow[u] == dfsNum[u]) {
49
- // cerr << "New scc: " << numSCC << endl;
50
64
while (true ) {
51
65
int v = S[--sctr]; vis[v] = false ;
52
66
sccNum[v] = numSCC;
53
67
sccSize[numSCC]++;
54
68
sccs[numSCC].pb (v);
55
- // cerr << v << " ";
56
69
if (v == u) break ;
57
70
}
58
71
reverse (all (sccs[numSCC]));
59
- // cerr << endl;
60
72
sccRoot[numSCC] = u;
61
73
++numSCC;
62
74
}
@@ -116,20 +128,19 @@ int main() {
116
128
}
117
129
}
118
130
}
119
- // SOMETHING HERE IS TIMING OUT
131
+
120
132
prev = sccs[i][prev];
121
133
if (prev != sccs[i][0 ]) {
134
+ int iter = 0 ;
122
135
while (!iToJ[prev][sccs[i][0 ]]) {
123
- // cerr << prev << " " << nextInSCC[prev] << endl ;
136
+ assert (++iter <= n) ;
124
137
if (prevInSCC[prev] == -1 ) {
125
- // return 0;
126
138
assert (false );
127
139
}
128
- int k = prevInSCC[prevInSCC[prev] ];
140
+ int k = sccs[i][ 0 ];
129
141
while (!iToJ[k][prev] || !iToJ[prev][nextInSCC[k]]) {
130
- k = prevInSCC [k];
142
+ k = nextInSCC [k];
131
143
if (k == -1 ) {
132
- // return 0;
133
144
assert (false );
134
145
}
135
146
}
@@ -140,14 +151,12 @@ int main() {
140
151
prevInSCC[prev] = k;
141
152
assert (oldNext != prev);
142
153
if (!iToJ[prev][oldNext]) {
143
- // return 0;
144
154
assert (false );
145
155
}
146
156
nextInSCC[prev] = oldNext;
147
157
prevInSCC[oldNext] = prev;
148
158
prev = nextPrev;
149
159
if (prev == -1 ) {
150
- // return 0;
151
160
assert (false );
152
161
}
153
162
}
@@ -170,50 +179,37 @@ int main() {
170
179
}
171
180
*/
172
181
173
- // for (int i = 0; i < numSCC; i++) {
174
- // for (int j = i+1; j < numSCC; j++) {
175
- // if (iToJ[sccRoot[i]][sccRoot[j]]) {
176
- // sccAdj[i].pb(j);
177
- // } else {
178
- // sccAdj[j].pb(i);
179
- // }
180
- // }
181
- // }
182
-
183
- // for (int i = 0; i < numSCC; i++) {
184
- // opt[i] = mp(0, -1);
185
- // vis[i] = false;
186
- // }
187
- // for (int i = 0; i < numSCC; i++) {
188
- // dfsScc(i);
189
- // }
190
-
191
- // string output;
192
- // for (int i = 0; i < n; i++) {
193
- // output += to_string(opt[sccNum[i]].f+sccSize[sccNum[i]]);
194
- // int cur = i;
195
- // int iterations = 0;
196
- // while (cur != -1) {
197
- // output += " " + to_string(cur+1);
198
- // // cerr << " " << cur+1;
199
- // int node = nextInSCC[cur];
200
- // while (node != cur) {
201
- // iterations++;
202
- // assert(iterations <= n);
203
- // output += " " + to_string(node+1);
204
- // // cerr << " " << node+1;
205
- // node = nextInSCC[node];
206
- // }
207
-
208
- // cur = opt[sccNum[cur]].s;
209
- // if (cur != -1) {
210
- // cur = sccRoot[cur];
211
- // }
212
- // }
213
- // cerr << endl;
214
- // output += "\n";
215
- // }
216
- // cout << output;
182
+ for (int i = 0 ; i < numSCC; i++) {
183
+ opt[i] = mp (0 , -1 );
184
+ vis[i] = false ;
185
+ }
186
+ for (int i = 0 ; i < numSCC; i++) {
187
+ dfsScc (i);
188
+ }
189
+
190
+ string output;
191
+ for (int i = 0 ; i < n; i++) {
192
+ output += to_string (opt[sccNum[i]].f +sccSize[sccNum[i]]);
193
+ int cur = i;
194
+ int iterations = 0 ;
195
+ while (cur != -1 ) {
196
+ output += " " + to_string (cur+1 );
197
+ int node = nextInSCC[cur];
198
+ while (node != cur) {
199
+ iterations++;
200
+ assert (iterations <= n);
201
+ output += " " + to_string (node+1 );
202
+ node = nextInSCC[node];
203
+ }
204
+
205
+ cur = opt[sccNum[cur]].s ;
206
+ if (cur != -1 ) {
207
+ cur = sccRoot[cur];
208
+ }
209
+ }
210
+ output += " \n " ;
211
+ }
212
+ cout << output;
217
213
218
214
return 0 ;
219
215
}
0 commit comments