import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.StringTokenizer; /** * ICPC Central Europe Regional Contest 2018 * Incorrect solution: Trees Gump *
* This solution compares angles absolutely (it does not take into account the "uplink" direction)
* and may therefore generate crossed links.
*
* @author Martin Kacer
*/
public class TreeGumpWrong1 {
StringTokenizer st = new StringTokenizer("");
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
boolean hasNextToken() {
try {
while (!st.hasMoreTokens()) {
String line = input.readLine();
if (line == null) return false;
st = new StringTokenizer(line);
}
} catch (IOException ex) { throw new RuntimeException(ex); }
return true;
}
String nextToken() {
return (!hasNextToken()) ? null : st.nextToken();
}
int nextInt() {
return Integer.parseInt(nextToken());
}
public static void main(String[] args) {
new TreeGumpWrong1().run();
}
static class Point { final int idx; final long x, y; Point(int idx, long x, long y) { this.idx = idx; this.x = x; this.y = y; } }
static class CompareByAngle implements Comparator> graph;
Point[] points;
int[] mapping, subsize;
void run() {
int n = nextInt();
graph = new ArrayList<>(n);
for (int i = 0; i < n; ++i) graph.add(new ArrayList<>());
for (int i = 1; i < n; ++i) {
int a = nextInt(), b = nextInt();
graph.get(a).add(b); graph.get(b).add(a);
}
points = new Point[n]; mapping = new int[n]; subsize = new int[n];
for (int i = 0 ; i < n; ++i) points[i] = new Point(i, nextInt(), nextInt());
Arrays.sort(points, 0, n, (a,b) -> Long.compare(a.y, b.y));
calcSubSize(0, -1);
process(0, -1, 0, n);
for (int a = 0; a < n; ++a)
for (int b : graph.get(a)) if (a < b) {
System.out.println(points[mapping[a]].idx + " " + points[mapping[b]].idx);
}
}
int calcSubSize(int root, int parent) {
int res = 1;
for (int n : graph.get(root)) if (n != parent)
res += calcSubSize(n, root);
return subsize[root] = res;
}
void process(int root, int parent, int fromIdx, int toIdx) {
mapping[root] = fromIdx;
int curidx = fromIdx+1;
Arrays.sort(points, curidx, toIdx, new CompareByAngle(points[fromIdx]));
for (int n : graph.get(root)) if (n != parent) {
process(n, root, curidx, curidx + subsize[n]);
curidx += subsize[n];
}
}
}