#include #include #include #include using namespace std; typedef long long llint; typedef pair pii; const int MAXN = 1010; vector e[MAXN]; pii p[MAXN]; int subtree[MAXN]; vector sol; llint ccw(pii a, pii b, pii c) { return (llint)a.first * (b.second - c.second) + (llint)b.first * (c.second - a.second) + (llint)c.first * (a.second - b.second); } void solve(int parent_coord, int parent_tree, vector points, int gp_tree) { /* printf("%d %d %d\n", parent_coord, parent_tree, gp_tree); for (int i = 0; i < (int)points.size(); ++i) { printf("=== %d \n", i); }*/ sort(points.begin(), points.end(), [&](int p1, int p2) { return ccw(p[parent_coord], p[p1], p[p2]) < 0; }); int l = 0; for (auto y : e[parent_tree]) { if (y == gp_tree) continue; sol.emplace_back(points[l], parent_coord); solve(points[l], y, vector(points.begin() + l + 1, points.begin() + l + subtree[y]), parent_tree); l += subtree[y]; } } void count_subtrees(int x, int parent) { subtree[x] = 1; for (auto y : e[x]){ if (y == parent) continue; count_subtrees(y, x); subtree[x] += subtree[y]; } } int main(void) { int n; scanf("%d", &n); for (int i = 0; i < n - 1; ++i) { int a, b; scanf("%d%d", &a,&b); e[a].push_back(b); e[b].push_back(a); } int root = 0; for (int i = 0; i < n; ++i) { int x, y; scanf("%d%d", &x, &y); p[i] = {x, y}; if (p[root] > p[i]) { root = i; } } count_subtrees(root, -1); // for (int i = 0; i < n; ++i) printf("%d\n", subtree[i]); vector points; for (int i = 0; i < n; ++i) { if (i == root) continue; points.push_back(i); } solve(root, 0, points, -1); for (auto x : sol) { printf("%d %d\n", x.first, x.second); } return 0; }