Codeforces 196 C. Paint Tree


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

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;
}


posted @ 2016-01-19 20:04  phlsheji  阅读(264)  评论(0编辑  收藏  举报