Pagini recente » Cod sursa (job #2185157) | Cod sursa (job #3219281) | Cod sursa (job #2268025) | Cod sursa (job #969541) | Cod sursa (job #2082548)
#include <algorithm>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <random>
#include <iostream>
#include <cassert>
#include <vector>
#define SZ(x) ((int) (x).size())
using namespace std;
struct ChooseMethod {
int a, b, c;
};
int qsort(const vector<ChooseMethod>& v, const vector<int>& values) {
vector<int> left, right;
if (SZ(values) <= 1) {
return 1;
}
int n = SZ(values);
int pivot = max({values[v[n].a], values[v[n].b], values[v[n].c]}) ^
min({values[v[n].a], values[v[n].b], values[v[n].c]}) ^
values[v[n].a] ^ values[v[n].b] ^ values[v[n].c];
for (int x: values) {
if (x < pivot) {
left.push_back(x);
} else if (x > pivot) {
right.push_back(x);
}
}
return 1 + max(qsort(v, left), qsort(v, right));
}
void fastRemove(vector<int>& a, int pos) {
memmove(a.data() + pos, a.data() + pos + 1, sizeof(int) * (SZ(a) - pos - 1));
a.resize(SZ(a) - 1);
}
int choose(vector<int>& values, const vector<ChooseMethod>& v,
vector<int>& rem, int val) {
if (val == 0) {
values[rem[0]] = val;
rem.pop_back();
return 0;
}
int len = val + 1;
ChooseMethod curr = v[len];
if (curr.a != curr.b && curr.b != curr.c && curr.c != curr.a) {
values[rem[curr.a]] = val;
values[rem[curr.b]] = val - 1;
fastRemove(rem, curr.a);
if (curr.b > curr.a) {
curr.b--;
}
fastRemove(rem, curr.b);
return 1 + choose(values, v, rem, val - 2);
} else if (curr.a == curr.b || curr.a == curr.c) {
values[rem[curr.a]] = val;
fastRemove(rem, curr.a);
return choose(values, v, rem, val - 1);
} else {
values[rem[curr.b]] = val;
fastRemove(rem, curr.b);
return choose(values, v, rem, val - 1);
}
}
pair<vector<int>, int> solve(const vector<ChooseMethod>& v) {
int n = SZ(v) - 1;
vector<int> rem;
for (int i = 0; i < n; ++i) {
rem.push_back(i);
}
vector<int> values(n, -1);
int sub = choose(values, v, rem, n - 1);
// if (find(values.begin(), values.end(), -1) != values.end()) {
// throw 1;
// }
// if (qsort(v, values) != n - sub) {
// throw 2;
// }
return make_pair(values, sub);
}
class Random {
public:
Random(int seed):
rnd(seed) {}
int nextInt(int n) {
int res = rnd() % n;
if (res < 0) {
res += n;
}
return res;
}
private:
mt19937 rnd;
};
void genRandomTestcases() {
Random rnd(time(0));
for (int t = 1; ; ++t) {
int n = rnd.nextInt(5000) + 10;
vector<ChooseMethod> v(n + 1);
for (int len = 2; len <= n; ++len) {
int a = rnd.nextInt(len);
int b = rnd.nextInt(len);
int c = rnd.nextInt(len);
v[len] = ChooseMethod{a, b, c};
}
try {
solve(v);
} catch (int) {
cerr << "Wrong on: " << endl;
cerr << n << endl;
for (int i = 2; i <= n; ++i) {
cerr << v[i].a << ' ' << v[i].b << ' ' << v[i].c << endl;
}
return;
}
cerr << "Done on test #" << t << "!" << endl;
}
}
int main() {
ifstream fin("sortare.in");
ofstream fout("sortare.out");
int n;
fin >> n;
vector<ChooseMethod> v(n + 1);
for (int i = 2; i <= n; ++i) {
fin >> v[i].a >> v[i].b >> v[i].c;
v[i].a--;
v[i].b--;
v[i].c--;
}
int sub;
vector<int> values;
tie(values, sub) = solve(v);
fout << n - sub << '\n';
for (int x: values) {
fout << x + 1 << ' ';
}
fout << '\n';
fin.close();
fout.close();
}