hihocoder1490 Tree Restoration 模拟

There is a tree of N nodes which are numbered from 1 to N. Unfortunately, its edges are missing so we don‘t know how the nodes are connected. Instead we know:

1. Which nodes are leaves

2. The distance (number of edges) between any pair of leaves

3. The depth of every node (the root‘s depth is 1)

4. For the nodes on the same level, their order from left to right

Can you restore the tree‘s edges with these information? Note if node u is on the left of node vu‘s parent should not be on the right of v‘s parent.

题意:有一颗树,给出叶子节点有哪些,叶子节点之间互相的距离,每个节点的深度,并且每层给定左右顺序,树边不交叉,要求复原树。

其实就是一个模拟题,我们可以知道,如果同一层两个叶子节点的距离是2,那么他们肯定是兄弟节点,而由于左右顺序给定,叶节点也给定,那么某一层最左边的两个叶子节点的父节点一定是上一层最左边的一个非叶子节点,而父节点和除子树外各节点的距离,其实是子节点和它们距离 - 1。我就能通过子节点得到父节点的距离信息了。

这个思路就可以做模拟了,我们对于最后一层从最左边的叶子节点开始,找到所有它的兄弟,它的距离顺便更新它的父节点的距离,之后父节点就可以当做叶节点了,然后继续操作同层所有的叶节点,寻找到父亲并更新父亲的距离。这样一层一层向上知道第二层就行。

模拟裸题。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<algorithm>
 5 using namespace std;
 6
 7 const int maxn=105;
 8 const int INF=0x3f3f3f3f;
 9 const int mod=1e9+7;
10
11 int n,m,k;
12
13 int vis[maxn];
14 int fa[maxn];
15 int mcnt[maxn];
16 int M[maxn][maxn];
17 int Map[maxn][maxn];
18 int a[maxn];
19
20 void update( int l ){
21     int f = fa[l];
22     for(int i = 1 ; i <= n ; ++ i ){
23         if( Map[l][i] != -1){
24             Map[f][i] = Map[i][f] = Map[l][i] - 1;
25         }
26     }
27 }
28
29 int main(){
30     memset(fa,-1,sizeof(fa));
31     scanf("%d%d%d",&n,&m,&k);
32     for(int i = 1 ; i <= m ; ++ i){
33         scanf("%d",&mcnt[i]);
34     }
35     for(int i = 1 ; i <= m ; ++ i){
36         for(int j = 1 ; j <= mcnt[i] ; ++ j){
37             scanf("%d",&M[i][j]);
38         }
39     }
40     memset(vis,0,sizeof(vis));
41     for(int  i = 1 ; i <= k ; ++ i){
42         scanf("%d",&a[i]);
43         vis[a[i]] = 1;
44     }
45     memset(Map,-1,sizeof(Map));
46     for(int i = 1 ; i <= k ; ++ i ){
47         for(int j = 1 ; j <= k ; ++ j ){
48             scanf("%d",&Map[a[i]][a[j]]);
49         }
50     }
51
52     for(int l = m ; l > 1 ; -- l ){
53         int S = l,F = l - 1;
54         int pos1 = 1,pos2 = 1;
55         while( pos2 <= mcnt[F] && vis[ M[F][pos2] ] )pos2++;
56         fa[ M[S][pos1] ] = M[F][pos2];
57         while( pos1 <= mcnt[S] ){
58             int l1 = M[S][pos1];
59             if(pos1 == mcnt[S] ){
60                 update( l1 );
61                 break;
62             }
63             else{
64                 int l2 = M[S][pos1+1];
65                 if( Map[l1][l2] != 2 ){
66                     update( l1 );
67                     pos2++;
68                     while( pos2 <= mcnt[F] && vis[ M[F][pos2] ] )pos2++;
69                 }
70                 fa[l2] = M[F][pos2];
71                 pos1++;
72             }
73         }
74     }
75     for(int i = 1 ; i <= n ; ++ i ){
76         if(fa[i] == -1 )printf("0");
77         else printf("%d",fa[i]);
78         if(i==n)printf("\n");
79         else printf(" ");
80     }
81     return 0;
82 }

时间: 2024-10-07 15:17:25

hihocoder1490 Tree Restoration 模拟的相关文章

HDU 4925 Apple Tree(模拟题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4925 解题报告:给你n*m的土地,现在对每一块土地有两种操作,最多只能在每块土地上进行两种操作,第一种是种苹果树操作,第二种是施肥操作,种苹果树操作可以使得该块地 长出一个苹果,施肥操作可以使得与这块土地相邻的土地的苹果产量变为原来的两倍,问可以得到的最多的苹果数量是多少? 例如一个4*4的土地,用1表示在该土地上做第一种操作,0表示在该土地上做第二种操作,可以得到最多苹果的操作如下: 0 1 0

【EasyUI学习-2】Easyui Tree的异步加载

作者:ssslinppp       1. 摘要 easyui相关的介绍可以上其官网或者百度去搜索,这里不做介绍. Easyui Tree的使用,官网或者easyui中文网站,也有相关介绍,但是官方提供的实例所使用的json是写死的,不是后台实时读取的.在实际的项目中,要显示的tree数据,一般都是从数据库中读取,然后通过通过ajax或者其他技术将tree的json数据发送到前台,然后显示. 本文将介绍easyui tree的异步加载,以及手动展开tree. 2. tree的相关介绍 上图是一个

【IOS 开发】IOS 开发 简介 (IOS项目文件 | MVC 模式 | 事件响应机制 | Storyboard 控制界面 | 代码控制界面 | Retina 屏幕图片适配)

一. IOS 项目简介 1. IOS 文件简介 创建一个 HelloWorld 项目, 在这个 IOS 项目中有四个目录 : 如下图; -- HelloWorldTests 目录 : 单元测试相关的类和资源; (1) HelloWorld 目录 HelloWorld 目录介绍 : -- 命名规则 : 该目录名称与 IOS 项目名称相同, 是主目录; -- 存放内容 : IOS 项目的 源码文件, 界面设计文件, 资源文件都存放在该目录下; -- 源文件 : Objective C 的 .m 和

【蓝桥杯竞赛】校门外的树

问题描述 某校大门外长度为 L 的马路上有一排树,每两棵相邻的树之间的间隔都是 1 米.我们 可以把马路看成一个数轴,马路的一端在数轴 0 的位置,另一端在 L 的位置:数轴上的每 个整数点,即 0,1,2,……,L,都种有一棵树.  由于马路上有一些区域要用来建地铁.这些区域用它们在数轴上的起始点和终止点表示.已 知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分.现在要把这些 区域中的树(包括区域端点处的两棵树)移走.你的任务是计算将这些树都移走后,马路上 还有多少棵树. 

Oracle 基础篇 --- B树索引内部结构

内部结构 将B树索引转储成树状结构的形式而呈现出来: alter session set events 'immediate trace name treedump level INDEX_OBJECT_ID'; SQL> alter session set events 'immediate trace name treedump level 126545'; Session altered. [[email protected] trace]$ pwd /home/oracle/app/or

响应国家号召,在家撸码之React迁移记

最近这段时间新型冠状病毒肆虐,上海确诊人数每天都在增加,人人提心吊胆,街上都没人了.为了响应国家号召,近期呆在家里撸码,着手将项目迁移到React中,项目比较朴素,是一张线索提交页面,包含表单.图片滚动等功能. 一.目录结构 项目基于Create React App构建而成,简单的做了下二次封装,src目录的结构如下所示. ├── src │ ├── __tests__ ---------------------- 测试文件 │ ├── common ----------------------

java代码模拟DOS下的tree命令

DOS下的tree命令可以把当前路径当做根路径,然后把文件树以树的形式展示出来.这个命令的实现不难,深搜一下文件树就可以了. import java.io.File; import java.util.Scanner; public class Tree { public static int depth = 0; public static void main(String[] args) { Scanner cin = new Scanner(System.in); String path

hdu6121 Build a tree 模拟

/** 题目:hdu6121 Build a tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6121 题意:n个点标号为0~n-1:节点i的父节点为floor((i-1)/k); 0是根节点. 求这个树的所有节点为根的子树的节点数的异或和. 思路:模拟 可以发现k = min(k,n-1):即:k>=n-1时候结果一样. 然后画图可以发现是一个满k叉树(叶子不一定满). 然后发现:如果这是一个叶子也满的k叉树,那么直接就可以计算出结果. 当不

easyui Tree模拟级联勾选cascadeCheck,节点选择,父节点自动选中,节点取消,父节点自动取消选择,节点选择,所有子节点全部选择,节点取消,所有子节点全部取消勾选

最近项目中用到easyui tree,发现tree控件的cascadeCheck有些坑,不像miniui 的tree控件,级联勾选符合业务需求,所以就自己重新改写了onCheck事件,符合业务需求.网上百度了很多资料,都没有完全符合自己业务场景的,所以就自己动手写咯. 先说一下自己的业务需求: 1.选中节点,上级以及所有直系上级节点自动选中,所有下级子孙节点全部自动选中: 2.取消选择节点,如果兄弟节点都未选择,则上级以及所有直系上级节点自动取消选择,所有下级子孙节点全部取消选中. 这里说一下c