• #1490 : Tree Restoration-(微软2017在线笔试)


    输入
    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=105;
    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,0,sizeof(isleaves));
        memset(son,0,sizeof(son));
        memset(dis,0,sizeof(dis));
    
        for(int i=0;i<m;i++){
            scanf("%d",&depth[i]);
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<depth[i];j++){
                scanf("%d",&layer[i][j]);
            }
        }
        for(int i=0;i<k;i++){
            scanf("%d",&leaves[i]);
            isleaves[leaves[i]]=1;
        }
        for(int i=0;i<k;i++){
            for(int j=0;j<k;j++){
                scanf("%d",&dis[leaves[i]][leaves[j]]);
            }
        }
        fa[layer[0][0]]=0;
        for(int i=0;i<depth[1];i++)
            fa[layer[1][i]]=layer[0][0];
        for(int i=m-1;i>=2;i--){
            int point=0;//i-1层中第一个不是叶子节点的节点,必定是当前节点的父亲
            while(isleaves[layer[i-1][point]] && point<depth[i-1]){
                point++;
            }
            int u=layer[i][0];
            fa[u]=layer[i-1][point];
            son[layer[i-1][point]]=u;
            //不能只更新父节点到其它叶子节点的距离,而是到其它所有点的距离
            for(int kk=0;kk<n;kk++){
                if(dis[u][kk]>0){
                    dis[fa[u]][kk]=dis[kk][fa[u]]=dis[u][kk]-1;
                }
            }
            for(int kk=0;kk<k;kk++){
                dis[leaves[kk]][fa[u]]=dis[fa[u]][leaves[kk]]=dis[leaves[kk]][u]-1;
            }
            for(int j=1;j<depth[i];j++){
                int v=layer[i][j];
                //如果和上一个节点u距离为2,说明父亲节点是同一个
                if(dis[u][v]==2){
                    fa[v]=fa[u];
                }
                //否则,父亲节点是i-1层中下一个不是叶子节点的节点
                else {
                    point++;
                    while(isleaves[layer[i-1][point]] && point<depth[i-1]){
                        point++;
                    }
                    fa[v]=layer[i-1][point];
                    son[layer[i-1][point]]=v;
                    //更新父亲节点到其它节点的距离
                    for(int kk=0;kk<n;kk++){
                        if(dis[v][kk]>0){
                            dis[fa[v]][kk]=dis[kk][fa[v]]=dis[v][kk]-1;
                        }
                    }
                }
                u=v;
            }
            //更新i-1层相邻节点的距离
            for(int kk=0;kk<depth[i-1]-1;kk++){
                int na=layer[i-1][kk];
                int nb=layer[i-1][kk+1];
                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]-2;
                }
            }
        }
        printf("%d",fa[1]);
        for(int i=2;i<=n;i++){
            printf(" %d",fa[i]);
        }
        //printf("
    ");
        return 0;
    }
    View Code
  • 相关阅读:
    Saltstack_使用指南09_远程执行-编写执行模块
    Saltstack_使用指南08_远程执行-返回程序
    Saltstack_使用指南07_远程执行-执行模块
    Saltstack_使用指南06_远程执行-指定目标
    CentOS7 Docker私有仓库搭建及删除镜像 【转】
    Python Docker 查看私有仓库镜像【转】
    Saltstack_使用指南05_数据系统-Pillar
    Saltstack_使用指南04_数据系统-Grains
    Saltstack_使用指南03_配置管理
    Saltstack_使用指南02_远程执行-验证
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/6675159.html
Copyright © 2020-2023  润新知