Paint Tree

题意:

给定一棵n个点的树,给定平面上n个点,将n个点用线段连起来画成树的形状,使得不存在不在端点相交的线段,构造出一种情况。

 

解法:

首先观察我们常规画出来的树形图可知,树的子树是根据极角分开的,这样,我们每一次找到最靠左下的点,

而后对剩余点极角排序,根据子树大小和极角的连续关系将点集划分,依次递归即可。

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 
  7 #define N 1510
  8 #define LL long long
  9 #define p E[i].x
 10 #define LD double
 11 #define pi acos(-1)
 12 
 13 using namespace std;
 14 
 15 struct edge
 16 {
 17     int x,to;
 18 }E[N<<1];
 19 
 20 struct node
 21 {
 22     LL x,y;
 23     LD v;
 24     int id;
 25     void scan()
 26     {
 27         scanf("%I64d%I64d",&x,&y);
 28     }
 29 }a[N],ans[N],root;
 30 
 31 int n,totE;
 32 int g[N],fa[N],siz[N],ansv[N];
 33 
 34 void addedge(int x,int y)
 35 {
 36     E[++totE]=(edge){y,g[x]}; g[x]=totE;
 37     E[++totE]=(edge){x,g[y]}; g[y]=totE;
 38 }
 39 
 40 void dfs(int x)
 41 {
 42     siz[x]=1;
 43     for(int i=g[x];i;i=E[i].to)
 44         if(p!=fa[x])
 45         {
 46             fa[p]=x;
 47             dfs(p);
 48             siz[x]+=siz[p];
 49         }
 50 }
 51 
 52 bool cmp(node a,node b)
 53 {
 54     LL tmp1=(a.x-root.x)*(b.y-root.y);
 55     LL tmp2=(a.y-root.y)*(b.x-root.x);
 56     return tmp1<tmp2;
 57 }
 58 
 59 void solve(int x,int l,int r)
 60 {
 61     int t=l;
 62     for(int i=l+1;i<=r;i++)
 63         if(a[i].x<a[t].x || (a[i].x==a[t].x && a[i].y<a[t].y))
 64             t=i;
 65     swap(a[t],a[l]);
 66     root=ans[x]=a[l];
 67     l++;
 68     if(l>r) return;
 69     sort(a+l,a+r+1,cmp);
 70     for(int i=g[x];i;i=E[i].to)
 71         if(p!=fa[x])
 72         {
 73             solve(p,l,l+siz[p]-1);
 74             l=l+siz[p];
 75         }
 76 }
 77 
 78 int main()
 79 {
 80     while(~scanf("%d",&n))
 81     {
 82         for(int i=1;i<=n;i++) g[i]=0;
 83         totE=0;
 84         for(int i=1,x,y;i<n;i++)
 85         {
 86             scanf("%d%d",&x,&y);
 87             addedge(x,y);
 88         }
 89         dfs(1);
 90         for(int i=1;i<=n;i++)
 91         {
 92             a[i].scan();
 93             a[i].id=i;
 94         }
 95         solve(1,1,n);
 96         for(int i=1;i<=n;i++) ansv[ans[i].id]=i; 
 97         for(int i=1;i<=n;i++) printf("%d ",ansv[i]);
 98         printf("\n");
 99     }
100     return 0;
101 }
View Code

 

posted @ 2017-03-08 21:57  lawyer'  阅读(119)  评论(0编辑  收藏  举报