• 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("
    ");
     99     }
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    稳如车!半个世纪过去了,康威定律依然适用
    task.factory.startnew()
    RabbitMQ基础知识
    NLog类库使用探索——详解配置
    C# winform开发嵌套Chrome内核浏览器(WebKit.net)开发(一)
    C#客户端嵌入Chrome浏览器的实现
    TLS/HTTPS 证书生成与验证
    SSL证书/TLS证书是什么
    htmlparser
    动软代码生成器之模板功能介绍
  • 原文地址:https://www.cnblogs.com/lawyer/p/6523285.html
Copyright © 2020-2023  润新知