#include <iostream>
#include <vector>
// #include <unistd.h>
using namespace std;
struct node
{
int parent;
int jump;
};
void printNode(node &node)
{
cout << "(";
if (node.parent >= 0)
cout << " ";
cout << node.parent << ", ";
if (node.jump >= 0)
cout << " ";
cout << node.jump << ") ";
}
void printNodes(vector<vector<node>> &nodes)
{
for (int i = 0; i < nodes.size(); i++)
{
for (int j = 0; j < nodes[i].size(); j++)
{
printNode(nodes[i][j]);
}
cout << endl;
}
}
int main()
{
int n, k;
cin >> n >> k;
vector<vector<node>> nodes(n);
nodes[0].resize(k, {-1, -1});
int nodesToVisit = k;
// input
for (int i = 1; i < n; i++)
{
int length;
cin >> length;
nodesToVisit += length;
vector<node> nodesToAdd(length);
for (int j = 0; j < length; j++)
{
int parent;
cin >> parent;
nodesToAdd[j] = {parent - 1, -1};
}
nodes[i] = nodesToAdd;
}
// printNodes(nodes);
int currentGlobalLayer = n - 1;
// to quickly pick next node in a given layer
vector<int> nextIndex(n);
int counter = 0;
// cout << "nodesToVisit: " << nodesToVisit << endl;
int endDetectorCounter = 0;
while (1)
{
// sleep(1);
int currentLayer = currentGlobalLayer;
endDetectorCounter = 0;
while (currentLayer >= 0)
{
// cout << "*****************" << endl;
// printNodes(nodes);
// cout << "*****************" << endl
// << endl;
// free pick part
// cout << "currentLayer: " << currentLayer << endl;
// cout << "nextIndex[currentLayer] = " << nextIndex[currentLayer] << endl;
int currentIndex = nextIndex[currentLayer];
if (currentIndex == nodes[currentLayer].size())
{
// cout << "current index out of bounds, going to next layer" << endl;
currentLayer--;
endDetectorCounter++;
// currentGlobalLayer--;
continue;
}
// cout << "current node: ";
// printNode(nodes[currentLayer][currentIndex]);
// cout << endl;
if (nodes[currentLayer][currentIndex].jump != -1)
{
// cout << "node is visited! continuing in the same layer" << endl;
nextIndex[currentLayer]++;
continue;
}
// we have fresh node
// prepare for next dfs run
nextIndex[currentLayer] = currentIndex + 1;
// dfs
vector<node> path;
// leafs are redundant here
path.push_back({currentIndex, currentLayer});
while (nodes[currentLayer][currentIndex].parent != -1)
{
currentIndex = nodes[currentLayer][currentIndex].parent;
currentLayer--;
// check if parent is visited
if (nodes[currentLayer][currentIndex].jump != -1)
{
// cout << "parent is visited! setting layer to jump" << endl;
// nextIndex[currentLayer]++;
currentLayer = nodes[currentLayer][currentIndex].jump;
break;
}
path.push_back({currentIndex, currentLayer});
}
// now we are in the root
int rootLayer = currentLayer;
// set jump for all visited nodes
// cout << "setting jump (jump = layer here)" << endl;
for (int i = 0; i < path.size(); i++)
{
// printNode(path[i]);
int parent = path[i].parent;
int layer = path[i].jump; // piggybacking off this field
nodes[layer][parent].jump = rootLayer;
}
// cout << endl;
// continue on a lower layer
currentLayer--;
}
if (endDetectorCounter == n)
{
// all layers visited
cout << counter << endl;
return 0;
}
counter++;
// cout << "incremented counter, now: " << counter << endl;
}
return 0;
}
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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | #include <iostream> #include <vector> // #include <unistd.h> using namespace std; struct node { int parent; int jump; }; void printNode(node &node) { cout << "("; if (node.parent >= 0) cout << " "; cout << node.parent << ", "; if (node.jump >= 0) cout << " "; cout << node.jump << ") "; } void printNodes(vector<vector<node>> &nodes) { for (int i = 0; i < nodes.size(); i++) { for (int j = 0; j < nodes[i].size(); j++) { printNode(nodes[i][j]); } cout << endl; } } int main() { int n, k; cin >> n >> k; vector<vector<node>> nodes(n); nodes[0].resize(k, {-1, -1}); int nodesToVisit = k; // input for (int i = 1; i < n; i++) { int length; cin >> length; nodesToVisit += length; vector<node> nodesToAdd(length); for (int j = 0; j < length; j++) { int parent; cin >> parent; nodesToAdd[j] = {parent - 1, -1}; } nodes[i] = nodesToAdd; } // printNodes(nodes); int currentGlobalLayer = n - 1; // to quickly pick next node in a given layer vector<int> nextIndex(n); int counter = 0; // cout << "nodesToVisit: " << nodesToVisit << endl; int endDetectorCounter = 0; while (1) { // sleep(1); int currentLayer = currentGlobalLayer; endDetectorCounter = 0; while (currentLayer >= 0) { // cout << "*****************" << endl; // printNodes(nodes); // cout << "*****************" << endl // << endl; // free pick part // cout << "currentLayer: " << currentLayer << endl; // cout << "nextIndex[currentLayer] = " << nextIndex[currentLayer] << endl; int currentIndex = nextIndex[currentLayer]; if (currentIndex == nodes[currentLayer].size()) { // cout << "current index out of bounds, going to next layer" << endl; currentLayer--; endDetectorCounter++; // currentGlobalLayer--; continue; } // cout << "current node: "; // printNode(nodes[currentLayer][currentIndex]); // cout << endl; if (nodes[currentLayer][currentIndex].jump != -1) { // cout << "node is visited! continuing in the same layer" << endl; nextIndex[currentLayer]++; continue; } // we have fresh node // prepare for next dfs run nextIndex[currentLayer] = currentIndex + 1; // dfs vector<node> path; // leafs are redundant here path.push_back({currentIndex, currentLayer}); while (nodes[currentLayer][currentIndex].parent != -1) { currentIndex = nodes[currentLayer][currentIndex].parent; currentLayer--; // check if parent is visited if (nodes[currentLayer][currentIndex].jump != -1) { // cout << "parent is visited! setting layer to jump" << endl; // nextIndex[currentLayer]++; currentLayer = nodes[currentLayer][currentIndex].jump; break; } path.push_back({currentIndex, currentLayer}); } // now we are in the root int rootLayer = currentLayer; // set jump for all visited nodes // cout << "setting jump (jump = layer here)" << endl; for (int i = 0; i < path.size(); i++) { // printNode(path[i]); int parent = path[i].parent; int layer = path[i].jump; // piggybacking off this field nodes[layer][parent].jump = rootLayer; } // cout << endl; // continue on a lower layer currentLayer--; } if (endDetectorCounter == n) { // all layers visited cout << counter << endl; return 0; } counter++; // cout << "incremented counter, now: " << counter << endl; } return 0; } |
English