Codeforces Round #124 (Div. 1) 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?≤?n, ui?≠?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 the i-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.

Examples

Input

31 32 30 01 12 0

Output

1 3 2

Input

41 22 31 4-1 -23 5-3 32 0

Output

4 2 1 3【分析】题意比较简单。给你一棵n个节点的树,再给你几何平面内的n个点,没有三点共线, 问你能不能用着n个点在几何平面内表现出来,线段除了顶点处无其他交点。 由于没有3点共线的情况,所以解总是存在的。 我们考虑以当前平面左下角的点p作为树根,对平面上的点以p做基准进行极角排序,则所有点与p点的连线都不会有除了p以外的交点。 现在我们已经会填树根处的点了,对于树根的每个子节点,我们都可以递归的处理以其为根的子树, 假设该子树包含x个节点,我们考虑以一根从p出发,长度不限的射线,从p的正下方开始按逆时针扫过去, 直到扫过的平面包含x个节点即可停止。此时扫过的平面即为该子树应当处理的平面。 每次处理需要先找到左下角的点,然后对当前平面的所有点进行排序,共需要处理n次,所以复杂度O(n^2*logn)。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
typedef long long ll;
using namespace std;
const int N = 2005;
const int M = 24005;
pair<ll,ll>ori;
vector<ll>edg[N];
ll n,m,k;
ll sz[N],ans[N];
struct man{
    ll x,y,id;
    bool operator < (const man & b) const {
        return (x-ori.first)*(b.y-ori.second) - (y-ori.second)*(b.x-ori.first) > 0;
    }
}p[N];
void dfs1(ll u,ll fa){
    sz[u]=1;
    for(int i=0;i<edg[u].size();i++){
        ll v=edg[u][i];
        if(v==fa)continue;
        dfs1(v,u);
        sz[u]+=sz[v];
    }
}
void dfs2(ll u,ll fa,ll s,ll e){
    int pos;
    ll x,y;
    x=y=1e10;
    for(int i=s;i<=e;i++){
        if(p[i].x<x||((p[i].x==x)&&p[i].y<y)){
            x=p[i].x;y=p[i].y;pos=i;
        }
    }
    ori.first=x;ori.second=y;
    swap(p[s],p[pos]);
    sort(p+s+1,p+e+1);
    ans[p[s].id]=u;
    int cnt=0;
    for(int i=0;i<edg[u].size();i++){
        ll v=edg[u][i];
        if(v==fa)continue;
        dfs2(v,u,s+1+cnt,s+1+cnt+sz[v]-1);
        cnt+=sz[v];
    }
}
int main() {
    ll T,u,v;
    scanf("%lld",&n);
    for(int i=1;i<n;i++){
        scanf("%lld%lld",&u,&v);
        edg[u].pb(v);edg[v].pb(u);
    }
    for(int i=0;i<n;i++){
        scanf("%lld%lld",&p[i].x,&p[i].y);
        p[i].id=i;
    }
    dfs1(1,0);
    dfs2(1,0,0,n-1);
    for(int i=0;i<n;i++)printf("%lld ",ans[i]);printf("\n");
    return 0;
}
时间: 2024-08-13 02:39:01

Codeforces Round #124 (Div. 1) C. Paint Tree(极角排序)的相关文章

Codeforces Round #245 (Div. 1)——Guess the Tree

本文出自:http://blog.csdn.net/svitter 实验环境:Myeclipse10 + tomcat7.0 有时间会写windows和linux下的tomcat配置,现在时间有限,暂且不写了..有些东西也是没有理解透彻. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <%@ page language="java" contentType="

Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/problem/C Description Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numb

343D/Codeforces Round #200 (Div. 1) D. Water Tree dfs序+数据结构

D. Water Tree Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a reservoir which can be either empty or filled with water. The vertices of the tree are numbered from 1 to n with the root at vertex 1. For

Codeforces Round #168 (Div. 1) B. Zero Tree 树形dp

题目链接: http://codeforces.com/problemset/problem/274/B 题意: 给出一棵树,每个点有权值,每次操作可以对一个联通子集中的点全部加1,或者全部减1,且每次操作必须包含点1,问最少通过多少次操作可以让整棵树每个点的权值变为0. 思路: http://blog.csdn.net/qq_24451605/article/details/48622953 定义状态up[u],down[u]代表点u被加操作的次数和点u被减操作的次数 因为必须包含点1,所以我

Codeforces Round #225 (Div. 2)---E. Propagating tree(时间戳+线段树)

Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numbered from 1 to n, each node i having an initial value ai. The root of the tree is node 1. This tree has a special propert

Codeforces Round #392 (div.2) E:Broken Tree

orz一开始想不画图做这个题(然后脑袋就炸了,思维能力有待提高) 我的做法是动态规划+贪心+构造 首先把题目给的树变成一个可行的情况,同时weight最小 这个可以通过动态规划解决 dp[x]表示以x为结点的子树,它的最小weight是多少 接着我们就只需要考虑每条边增加多少就可以了,这里可以用贪心的做法 ddfs(int x, int fa, int v) 这里v是表示给x结点最大多少增量,然后慢慢加就可以,返回没用掉的增量 其实这个做法有点奇怪,应该有更简便的做法(我觉得可以直接贪心做) #

Codeforces Round #200 (Div. 1) D. Water Tree(dfs序加线段树)

思路: dfs序其实是很水的东西.  和树链剖分一样, 都是对树链的hash. 该题做法是:每次对子树全部赋值为1,对一个点赋值为0,查询子树最小值. 该题需要注意的是:当我们对一棵子树全都赋值为1的时候, 我们要查询一下赋值前子树最小值是不是0, 如果是的话, 要让该子树父节点变成0, 否则变0的信息会丢失. 细节参见代码: #include <cstdio> #include <cstring> #include <algorithm> #include <i

Codeforces Round #281 (Div. 2) C. Vasya and Basketball 排序

C. Vasya and Basketball Vasya follows a basketball game and marks the distances from which each team makes a throw. He knows that each successful throw has value of either 2 or 3 points. A throw is worth 2 points if the distance it was made from does

Codeforces Round #460 (Div. 2)_D. Substring_[dp][拓扑排序]

题意:一个有向图,每个结点 被赋予一个小写字母,一条路径的value等与这条路径上出现次数最多的字母的数目,求该图的最大value 比赛时,用dfs超时,看官方题解用的dp和拓扑排序,a--z用0-25表示,用dp[i][j]表示以第i个结点结尾的路径上第j个字母出现的次数 拓扑排序每排到一个点,就用该点的dp去更新与它相邻点的dp,最开始入度为0的点特殊处理了一下,dp过程中同步更新结果res 也复习了一下拓扑排序 #include<iostream> #include<cstdio&