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 }

时间: 2025-01-04 07:24:05

Paint Tree的相关文章

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

Codeforces 196C Paint Tree(贪心+极角排序)

题目链接 Paint Tree 给你一棵n个点的树和n个直角坐标系上的点,现在要把树上的n个点映射到直角坐标系的n个点中,要求是除了在顶点处不能有线段的相交. 我们先选一个在直角坐标系中的最左下角的点,把根结点放到这个点中,然后对剩下的点进行极角排序,按逆时顺序一个个塞进来,类似地递归处理. 这样就满足了题意. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b

CodeForces 196C.Paint Tree(分治+极角排序)

C. Paint Tree time limit per test 2 seconds memory limit per test 256 megabytes 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

装饰器模式及JAVA IO流例子★★★☆☆

一.什么是装饰模式 通过关联机制给类增加行为,其行为的扩展由修饰对象来决定: 二.补充说明 与继承相似,不同点在于继承是在编译期间扩展父类,而装饰器模式在运行期间动态扩展原有对象: 或者说,继承是对类进行扩展,装饰模式是对对象进行扩展: 三.角色 抽象构件 具体构件 抽象装饰类 具体装饰类 说明:具体构件.抽象装饰类.具体装饰类的共同父类是抽象构件,具体装饰类继承抽象装饰类并在运行期间装饰具体构件: 四.例子 例子说明: 画家接口Painter,为抽象构件,有两个方法,获取画家描述信息及绘画:

bzoj3638

费用流+线段树 看见这个题我们马上就能想到费用流,设立源汇,分别向每个点连接容量为1费用为0的边,然后相邻的点之间连边,费用为点权,跑费用流就行了,但是很明显这样会超时,那么我们要优化一下,我们观察费用流的过程,发现对于点与点之间的边,每次取一段区间相当于把正向边改为反向边,费用变负,于是我们可以用线段树来模拟这个过程,像费用流一样贪心地选取区间的最大子段和,然后取反,每次取k次,然后恢复.这样就好了 但是写的时候有很多问题,比如如何返回一个区间?结构体!参考了popoqqq大神的代码,发现我们

E. Paint the Tree(树形dp)

题:https://codeforces.com/contest/1241/problem/E 题目大意:给你一棵树,每一个点都可以染k种颜色,你拥有无数种颜色,每一种颜色最多使用2次,如果一条边的两个节点拥有同一种颜色,那么就说 这条边是饱和的,一个树的价值定义为饱和边的权值之和,问一棵树的最大价值是多少. #include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const

【CF1244D】Paint the Tree(树形DP)

题意: n<=1e5,1<=a[i][j]<=1e9 思路: 不是很懂INF为什么要开到1e15,我觉得只要1e14就好 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typede

Codeforces 1244D Paint the Tree(染色+排列)

链接:https://codeforces.com/problemset/problem/1244/D 题意:给一个树染上三种颜色,保证每一段长度为3的链颜色都不相同. 题解:颜色很少可以发现,当且仅当这个树是一条链的时候才满足条件(记录度数即可), 对这条链进行暴力染色即可,确定前三个即可确定整条链. #include <bits/stdc++.h> #define IO_read ios::sync_with_stdio(false);cin.tie(0) #define fre freo

cf 1244 D. Paint the Tree

题意: 有一颗树,n个点,让你涂色,有三种颜色,每个节点每涂一种颜色都有一种成本.要求,所有连续的三个点都要有不同的颜色,并且总成本要最小. 无法满足就输出-1,否则输出成本和方案. 思路: 显然,如果有一个点的度>=3,那么肯定不满足,所以一定得是一条链. 如果头两个的颜色确定了,那么接下来的n-2个点的颜色也就确定了, 所以其实只有6种情况,模拟一下就好了. 代码: #include <stdio.h> #include <string.h> #include <c