Codeforces 196 C. Paint Tree

it2025-06-20  3

分治。选最左上的点分给根。剩下的极角排序后递归

C. Paint Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output

You are given a tree with n vertexes and n points on a plane, no three points lie on one straight line.

Your task is to paint the given tree on a plane, using the given points as vertexes.

That is, you should correspond each vertex of the tree to exactly one point and each point should correspond to a vertex. If two vertexes of the tree are connected by an edge, then the corresponding points should have a segment painted between them. The segments that correspond to non-adjacent edges, should not have common points. The segments that correspond to adjacent edges should have exactly one common point.

Input

The first line contains an integer n (1 ≤ n ≤ 1500) — the number of vertexes on a tree (as well as the number of chosen points on the plane).

Each of the next n - 1 lines contains two space-separated integers ui and vi (1 ≤ ui, vi ≤ nui ≠ vi) — the numbers of tree vertexes connected by the i-th edge.

Each of the next n lines contain two space-separated integers xi and yi ( - 109 ≤ xi, yi ≤ 109) — the coordinates of thei-th point on the plane. No three points lie on one straight line.

It is guaranteed that under given constraints problem has a solution.

Output

Print n distinct space-separated integers from 1 to n: the i-th number must equal the number of the vertex to place at the i-th point (the points are numbered in the order, in which they are listed in the input).

If there are several solutions, print any of them.

Sample test(s) input 3 1 3 2 3 0 0 1 1 2 0 output 1 3 2 input 4 1 2 2 3 1 4 -1 -2 3 5 -3 3 2 0 output 4 2 1 3 Note

The possible solutions for the sample are given below.

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn=1520; int n,X,Y; struct PO { int x,y,d; bool operator<(const PO &o) const { if(x-X>=0&&o.x-X<=0) return 1; if(x-X<=0&&o.x-X>=0) return 0; return (y-Y)*(long long)(o.x-X)<(o.y-Y)*(long long)(x-X); } }p[maxn]; vector<int> g[maxn]; bool vis[maxn]; int sz[maxn],o[maxn]; int dfs(int u) { vis[u]=true; sz[u]=1; int ret=0; for(int i=0,j=g[u].size();i<j;i++) { int v=g[u][i]; if(vis[v]) continue; ret+=dfs(v); } sz[u]+=ret; return sz[u]; } void calc(int u,int l,int r) { vis[u]=true; int t=l; for(int i=l+1;i<=r;i++) { if((p[i].y<p[t].y)||(p[t].y==p[i].y&&p[i].x<p[t].x)) t=i; } if(t!=l) swap(p[l],p[t]); o[p[l].d]=u; X=p[l].x; Y=p[l].y; sort(p+l+1,p+r+1); int pos=l+1; for(int i=0,j=g[u].size();i<j;i++) { int v=g[u][i]; if(vis[v]) continue; calc(v,pos,pos+sz[v]-1); pos+=sz[v]; } } int main() { scanf("%d",&n); for(int i=0;i<n-1;i++) { int x,y; scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } for(int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); p[i]=(PO){x,y,i}; } dfs(1); memset(vis,0,sizeof(vis)); calc(1,1,n); for(int i=1;i<=n;i++) printf("%d ",o[i]); putchar(10); return 0; }

转载于:https://www.cnblogs.com/bhlsheji/p/5143248.html

相关资源:数据结构—成绩单生成器
最新回复(0)