#include using namespace std; typedef long long int LL; #define st first #define nd second #define PII pair const int N = 1007; int n; int pod[N]; vector G[N]; vector C[N]; PII Points[N]; vector ini; int dfs(int u, int p){ pod[u] = 1; for(auto v: G[u]){ if(v == p) continue; pod[u] += dfs(v, u); C[u].push_back(v); } return pod[u]; } LL Iloczyn(PII a, PII b, PII c){ return 1LL * (b.st - a.st) * (c.nd - a.nd) - 1LL * (c.st - a.st) * (b.nd - a.nd); } LL kwa(LL a){ return a * a; } LL dist(PII a, PII b){ return kwa(a.st - b.st) + kwa(a.nd - b.nd); } PII c; bool cmp(int aa, int bb){ PII a = Points[aa], b = Points[bb]; bool at = (a.st > c.st) || (a.st == c.st && a.nd == c.nd); bool bt = (b.st > c.st) || (b.st == c.st && b.nd == c.nd); if(at != bt) return at; return Iloczyn(c, a, b) < 0; } void solve(vector cur, int root, int u){ if(cur.size() <= 1) return; for(int i = 0; i < cur.size(); ++i) if(cur[i] == root){ swap(cur[i], cur[cur.size() - 1]); cur.pop_back(); break; } c = Points[root]; sort(cur.begin(), cur.end(), cmp); int wsk = 0; vector nxt; for(int v: C[u]){ nxt.clear(); while(nxt.size() < pod[v]) nxt.push_back(cur[wsk++]); printf("%d %d\n", root, nxt[0]); solve(nxt, nxt[0], v); } } int main(){ scanf("%d", &n); for(int i = 1; i < n; ++i){ int u, v; scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } dfs(0, 0); for(int i = 0; i < n; ++i){ scanf("%d %d", &Points[i].st, &Points[i].nd); ini.push_back(i); } int LeftMost = 0; for(int i = 0; i < n; ++i) if(Points[i].st < Points[LeftMost].st) LeftMost = i; solve(ini, LeftMost, 0); return 0; }