输入
n m k
m个数,表示每层的节点个数
接下来m行是每层的节点,节点顺序是从左往右的
k个叶子节点
k*k个矩阵,表示叶子节点之间的距离

输出:
每个节点的父亲节点编号,root节点是0

题解:
1.很明显,相邻两个节点的距离如果是2,那么便是同一个父亲节点。
2.第一个点的父亲节点u,必定是上一层第一个非叶子节点fa
3.u左边的节点v
如果dis[u][v]==2,则fa[v]=fa[u]
否则,fa[v]为fa的下一个非叶子节点
所以很明显,dis矩阵得为n*n的大小,而不仅仅是k*k
4.由于一开始只知道各叶子节点之间的dis,所以从底层往上推。
每次求该层节点的父亲节点,同时更新上面一层的相邻节点的距离

一开始WA的原因是更新父节点的距离时,只更新了其到其它叶子节点的距离,没有更新到所有点的距离。。。
所以遇到下面的样例时候,dis[3][4]=-2,而不是2
1->2
2->3,2->4
3->5,3->6 4->7
5->8,5->9 6->10 7->11
11 5 4
1 1 2 3 4
1
2
3 4
5 6 7
8 9 10 11
8 9 10 11
0 2 4 6
2 0 4 6
4 4 0 6
6 6 6 0

错误的输出:0 1 2 0 3 3 4 5 5 6 7
正确的输出:0 1 2 2 3 3 4 5 5 6 7

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string.h>
using namespace std;
const int maxn=;
int n,m,k;
int depth[maxn]; //每层的节点个数
int layer[maxn][maxn]; //每层的节点
int fa[maxn]; //ans
int leaves[maxn]; //叶子节点
int isleaves[maxn]; //是否为叶子节点
int dis[maxn][maxn];
int son[maxn]; //父亲节点的随便其中一个儿子就行,因为点u到fa的所有儿子的距离都一样
int main()
{
scanf("%d %d %d",&n,&m,&k);
memset(isleaves,,sizeof(isleaves));
memset(son,,sizeof(son));
memset(dis,,sizeof(dis)); for(int i=;i<m;i++){
scanf("%d",&depth[i]);
}
for(int i=;i<m;i++){
for(int j=;j<depth[i];j++){
scanf("%d",&layer[i][j]);
}
}
for(int i=;i<k;i++){
scanf("%d",&leaves[i]);
isleaves[leaves[i]]=;
}
for(int i=;i<k;i++){
for(int j=;j<k;j++){
scanf("%d",&dis[leaves[i]][leaves[j]]);
}
}
fa[layer[][]]=;
for(int i=;i<depth[];i++)
fa[layer[][i]]=layer[][];
for(int i=m-;i>=;i--){
int point=;//i-1层中第一个不是叶子节点的节点,必定是当前节点的父亲
while(isleaves[layer[i-][point]] && point<depth[i-]){
point++;
}
int u=layer[i][];
fa[u]=layer[i-][point];
son[layer[i-][point]]=u;
//不能只更新父节点到其它叶子节点的距离,而是到其它所有点的距离
for(int kk=;kk<n;kk++){
if(dis[u][kk]>){
dis[fa[u]][kk]=dis[kk][fa[u]]=dis[u][kk]-;
}
}
for(int kk=;kk<k;kk++){
dis[leaves[kk]][fa[u]]=dis[fa[u]][leaves[kk]]=dis[leaves[kk]][u]-;
}
for(int j=;j<depth[i];j++){
int v=layer[i][j];
//如果和上一个节点u距离为2,说明父亲节点是同一个
if(dis[u][v]==){
fa[v]=fa[u];
}
//否则,父亲节点是i-1层中下一个不是叶子节点的节点
else {
point++;
while(isleaves[layer[i-][point]] && point<depth[i-]){
point++;
}
fa[v]=layer[i-][point];
son[layer[i-][point]]=v;
//更新父亲节点到其它节点的距离
for(int kk=;kk<n;kk++){
if(dis[v][kk]>){
dis[fa[v]][kk]=dis[kk][fa[v]]=dis[v][kk]-;
}
}
}
u=v;
}
//更新i-1层相邻节点的距离
for(int kk=;kk<depth[i-]-;kk++){
int na=layer[i-][kk];
int nb=layer[i-][kk+];
int sona,sonb;
/*只要有一方是叶子节点,那么dis已经有了
如果都不是,那么就是对应儿子节点之间的距离-1
因为是从底层往上推的,所以儿子所在那一层的相邻节点距离已经更新过了。
*/
if(!isleaves[na] && !isleaves[nb]){
sona=son[na];
sonb=son[nb];
dis[na][nb]=dis[nb][na]=dis[sona][sonb]-;
}
}
}
printf("%d",fa[]);
for(int i=;i<=n;i++){
printf(" %d",fa[i]);
}
//printf("\n");
return ;
}

#1490 : Tree Restoration-(微软2017在线笔试)的更多相关文章

  1. #1490 : Tree Restoration

    微软 2017春招真题 题目 There is a tree of N nodes which are numbered from 1 to N. Unfortunately, its edges a ...

  2. hihocoder 1490 Tree Restoration

    构造. 从最后一层开始往上构造.最后一层肯定都是叶子结点,距离为2的肯定是同一个父亲,确定好了父亲之后,可以确定上一层每个节点之间的距离,以及上一层每个节点到还未确定的叶子节点之间的距离. #incl ...

  3. 2016网易春招Java在线笔试回忆录

    别看是在线笔试,但是非常严格,全称窗口不得最小化和关闭,转移,全称需要打开摄像头监控,使用草稿纸需要摄像头对准……反正2个小时,题量在那儿摆着,有作弊的功夫不如好好做做最后的编程题呢……网易不让泄漏原 ...

  4. 美团点评2017校招笔试真题-算法工程师A

    美团点评2017校招笔试真题-算法工程师A 1.下面哪种STL容器的实现和其它三个不一样 A. set B. deque C. multimap D. map 正确答案: B STL的容器可以分为以下 ...

  5. 美团点评2017校招笔试真题-算法工程师B

    美团点评2017校招笔试真题-算法工程师B 1.以下关于经典的k-means聚类的说法哪个是错误的? A:k-means聚类算法是全局收敛的 B:k-means的聚类结果和初始聚类中心点的选取有关 C ...

  6. Python 在线笔试

    1. 循环输入输出交互 Python在线笔试琐碎 求两个整数 A+B 的和. while True: try: (n, m) = (int(x) for x in raw_input().split( ...

  7. 【微软2017年预科生计划在线编程笔试 B】Tree Restoration

    [题目链接]:https://hihocoder.com/problemset/problem/1490 [题意] 给你一棵树的以下信息: 1.节点个数 2.给出树的每一层从左到右的顺序每个节点的编号 ...

  8. hihocoder1489 Legendary Items (微软2017年预科生计划在线编程笔试)

    http://hihocoder.com/problemset/problem/1489 笔试题第一道,虽然说第一道都很水,但是我感觉这题不算特别水把..这道题我就卡住了我记得,tle,最后只有30分 ...

  9. 微软2017年预科生计划在线编程笔试 A Legendary Items

    思路: 获得第i(i = 0, 1, ..., n - 1)件物品的概率仅由公式p / (1 << i)决定,所以获得这i件物品之间是相互独立的.迭代计算获得所有i件物品的期望再求和即可. ...

随机推荐

  1. (转)Python学习笔记系列——Python是一种纯粹的语言

    此文出自知乎灵剑,原文传送门:https://zhuanlan.zhihu.com/p/23926957. 在摸索适合自己的语言学习方法,看到一篇好文章,转之,侵删. Python的语法范式相当多.知 ...

  2. 【题解】洛谷P1070 道路游戏(线性DP)

    次元传送门:洛谷P1070 思路 一开始以为要用什么玄学优化 没想到O3就可以过了 我们只需要设f[i]为到时间i时的最多金币 需要倒着推回去 即当前值可以从某个点来 那么状态转移方程为: f[i]= ...

  3. activiti基础环境搭建创建数据库表及策略

    博主使用为activiti5.22的版本. 1.创建maven工程. 2.在pom文件中引入所需要的包,如:activiti包.数据库包. 这是我引用的包: <dependencies> ...

  4. 【转】Vulhub - 开源的安全漏洞学习与复现项目

    转载于:https://uk.v2ex.com/t/485611#reply15 Vulhub 是一个面向大众的开源漏洞靶场,无需 docker 知识,简单执行两条命令即可编译.运行一个完整的漏洞靶场 ...

  5. 关于Quartus+Modelsim 门级仿真 Warning (vopt-2216) Cannot find instance 'NA' specified in sdf.的解决办法

    本文操作环境:Win 7 32位系统, Quartus II 11.1 ,Modelsim SE 10.1a 在Quartus II中调用Modelsim SE做Gate Level Simulait ...

  6. 20155327 2017-2018-2 《Java程序设计》第9周学习总结

    20155327 2017-2018-2 <Java程序设计>第9周学习总结 URL类 URL类是java.net包中的一个重要的类,URL的实例封装着一个统一资源定位符,使用URL创建对 ...

  7. Noip前的大抱佛脚----Noip真题复习

    Noip前的大抱佛脚----Noip真题复习 Tags: Noip前的大抱佛脚 Noip2010 题目不难,但是三个半小时的话要写四道题还是需要码力,不过按照现在的实力应该不出意外可以AK的. 机器翻 ...

  8. 【mysql】排序方法

    查询各科成绩前三名的记录,不考虑并列的情况: select a.course_id as 课程ID, a.score as 成绩, count(a.course_id) as 排名 from scor ...

  9. ELK批量删除索引

    一.存在问题 用了一段时间elk发现如果索引长时间不删除,elk会越来越慢,重启elasticsearch服务器节点之前同步时间也会很长 二.解决方法(定期删除索引) 1.在elasticsearch ...

  10. SSIS 数据流的错误输出

    数据流任务对错误的处理,和控制流不同,在数据流中,主要是对于错误行的处理,一般通过Error Output配置. 1,操作失败的类型:Error(Conversion) 和 Truncation. 2 ...