#include using namespace std; #define PII pair #define VI vector #define VPII vector #define LL long long #define f first #define s second #define MP make_pair #define PB push_back #define LD long double #define endl '\n' #define ALL(c) (c).begin(), (c).end() #define SIZ(c) (int)(c).size() #define REP(i, n) for (int i = 0; i < (int)(n); i++) #define FOR(i, b, e) for (int i = (b); i <= (int)(e); i++) #define FORD(i, b, e) for (int i = (b); i >= (int)(e); i--) #define ll LL #define mp MP #define pb PB #define st f #define nd s #define eb emplace_back const int inf = 1e9 + 7; const LL INF = 1e18L + 7; #define sim template ostream & operator << (ostream &p, pair x) {return p << "<" << x.f << ", " << x.s << ">";} sim> auto operator << (ostream &p, n y) -> typename enable_if::value, decltype(y.begin(), p)>::type {int o = 0; for (auto c : y) {if (o++) p << ", "; p << c;} return p << "}";} void dor() {cerr << endl;} sim, class...s> void dor(n p, s...y) {cerr << p << " "; dor(y...);} sim, class s> void mini(n &p, s y) {if (p > y) p = y;} sim, class s> void maxi(n &p, s y) {if (p < y) p = y;} #ifdef DEB #define debug(...) dor(__FUNCTION__, ":", __LINE__, ": ", __VA_ARGS__) #else #define debug(...) #endif #define I(x) #x " =", (x), " " #define A(a, i) #a "[" #i " =", i, "] =", a[i], " " const int MXN = 1003; VI V[MXN]; int siz[MXN]; int fat[MXN]; map nr; void dfs(int x, int pp) { fat[x] = pp; siz[x] = 1; for(auto i : V[x]) { if(i == pp)continue; dfs(i, x); siz[x] += siz[i]; } } #define y second #define x first #define PL pair LL det(PL p1, PL p2, PL w) { return (p2.x-p1.x) * (w.y - p1.y) - (p2.y - p1.y) * (w.x - p1.x); } int cw(PII a) { if(a.f >= 0 && a.s >= 0)return 1; if(a.f <= 0 && a.s >= 0)return 2; if(a.f <= 0 && a.s <= 0)return 3; return 4; } PII operator-=(PII &a, PII b) { a.f -= b.f; a.s -= b.s; return a; } int cmp(PII a, PII b, PII s) { a-=s; b-=s; if(cw(a) != cw(b))return cw(a) < cw(b); LL d = det(MP(0, 0), a, b); return d > 0 ? 1 : 0; } int numa[MXN]; void go(int v, VPII points) { debug(v, siz[v], points); assert(siz[v] == points.size()); sort(ALL(points), [](PII a, PII b){return MP(a.s, a.f) < MP(b.s, a.f);}); reverse(ALL(points)); PII mine = points.back(); points.pop_back(); numa[v] = nr[mine]; sort(ALL(points), [&](PII a, PII b){return cmp(a, b, mine);}); reverse(ALL(points)); // TODO: dodac for(auto i : V[v]) { if(i == fat[v])continue; VPII pom; while(pom.size() < siz[i]) { pom.PB(points.back()); points.pop_back(); } go(i, pom); } } /* 2 3 5 3 5 out Petyr */ int main() { /* PII mine = {0, 0}; VPII point = {MP(1, 1), MP(1, -1), MP(-1, 1), MP(-1, 1), MP(0, 1), MP(0, -1)}; sort(ALL(point), [&](PII a, PII b){return cmp(a, b, mine);}); debug(point); for(auto i : point) debug(i, cw(i)); // return 0; */ int n; cin >> n; FOR(i, 1, n-1) { int a, b; cin >> a >> b; a++; b++; V[a].PB(b); V[b].PB(a); } VPII points; FOR(i, 1, n) { int a, b; cin >> a >> b; points.PB(MP(a, b)); nr[MP(a, b)] = i - 1; } dfs(1, 0); go(1, points); FOR(i, 1, n) { for(auto j : V[i]) { if(i < j) cout << numa[i] << " " << numa[j] << endl; } } }