Skip to content

Commit 90b5070

Browse files
POI 17-tourist
1 parent 2483e2a commit 90b5070

File tree

1 file changed

+51
-55
lines changed

1 file changed

+51
-55
lines changed

POI/POI 17-Tourist.cpp

+51-55
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
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+
116
#include <bits/stdc++.h>
217

318
using namespace std;
@@ -46,17 +61,14 @@ void tarjan(int u) {
4661
}
4762

4863
if (dfsLow[u] == dfsNum[u]) {
49-
// cerr << "New scc: " << numSCC << endl;
5064
while (true) {
5165
int v = S[--sctr]; vis[v] = false;
5266
sccNum[v] = numSCC;
5367
sccSize[numSCC]++;
5468
sccs[numSCC].pb(v);
55-
// cerr << v << " ";
5669
if (v == u) break;
5770
}
5871
reverse(all(sccs[numSCC]));
59-
// cerr << endl;
6072
sccRoot[numSCC] = u;
6173
++numSCC;
6274
}
@@ -116,20 +128,19 @@ int main() {
116128
}
117129
}
118130
}
119-
// SOMETHING HERE IS TIMING OUT
131+
120132
prev = sccs[i][prev];
121133
if (prev != sccs[i][0]) {
134+
int iter = 0;
122135
while (!iToJ[prev][sccs[i][0]]) {
123-
// cerr << prev << " " << nextInSCC[prev] << endl;
136+
assert(++iter <= n);
124137
if (prevInSCC[prev] == -1) {
125-
// return 0;
126138
assert(false);
127139
}
128-
int k = prevInSCC[prevInSCC[prev]];
140+
int k = sccs[i][0];
129141
while (!iToJ[k][prev] || !iToJ[prev][nextInSCC[k]]) {
130-
k = prevInSCC[k];
142+
k = nextInSCC[k];
131143
if (k == -1) {
132-
// return 0;
133144
assert(false);
134145
}
135146
}
@@ -140,14 +151,12 @@ int main() {
140151
prevInSCC[prev] = k;
141152
assert(oldNext != prev);
142153
if (!iToJ[prev][oldNext]) {
143-
// return 0;
144154
assert(false);
145155
}
146156
nextInSCC[prev] = oldNext;
147157
prevInSCC[oldNext] = prev;
148158
prev = nextPrev;
149159
if (prev == -1) {
150-
// return 0;
151160
assert(false);
152161
}
153162
}
@@ -170,50 +179,37 @@ int main() {
170179
}
171180
*/
172181

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;
217213

218214
return 0;
219215
}

0 commit comments

Comments
 (0)