星星之火OIer:多叉树转二叉树

5 篇文章 0 订阅

好久没出博客了。。。

多叉树转二叉树

题目描述::

截图可方便了

方法:

举个栗子,如图::

好和谐啊

这是一棵多叉树

如何转化为二叉树??

  • 连接每一组兄弟,如图:

  • 把右儿子断掉,如图:

  • 然后再整理一下,就变成了:

  • 最后我们对比一下前后的变化:

然后就是处理森林。

还是来图例

比如就是上面的那棵树:

(copy真好用)

我们只需要把每一棵树的祖父节点放到连接到一起即可:

然而这个图好像有点复杂,我们来看一个简化版的:

先连成这个样子:

再整理一下:

再连另一个,最后应该是这个样子的:

 

实现::

其实实现起来也挺简单的。

现在输入a和b两个节点,把b加到a上。

我们只要按上述步骤。

先判断a有没有左儿子

如果没有,那么b就成为a的左儿子。

图例:

(用鼠标写字很难看不要介意:-) )

如果有,那就一直寻找到此节点的右儿子为空为止。

图例:

遇见森林只需要暴力转换就可以了。

代码::

#include<cstdio>
#include<algorithm>
using namespace std;
inline void read(int &x) {
    x=0;
    int f=1;
    char s=getchar();
    while(s<'0'||s>'9') {
        if(s=='-')
            f=-1;
        s=getchar();
    }
    while(s>='0'&&s<='9') {
        x=x*10+s-48;
        s=getchar();
    }
    x*=f;
}
inline void pr(int x) {
    if(x<0) {
        putchar('-');
        x=-x;
    }
    if(x>9)
        pr(x/10);
    putchar(x%10+48);
}//快读快输不解释
struct node {
    int l,r,fa;
}s[105];
int n,m,x,y,a[105],tot;
bool flag[105][105];
void sl() {
    for(int i=1;i<=n;i++)
        if(!s[i].fa)
            a[++tot]=i;
    for(int i=tot;i>1;i--) {
        s[a[i-1]].r=a[i];
        s[a[i]].fa=a[i-1];
    }
}
int main() {
    read(n),read(m);
    for(int i=1;i<=m;i++) {
        read(x),read(y);
        flag[x][y]=1;//先读入,再处理
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(flag[i][j])//父亲与儿子
                if(s[i].l==0) {//按照刚刚的,左儿子没有
                    s[i].l=j;//直接变成这个节点的左儿子
                    s[j].fa=i;//更新父亲节点编号
                }
                else {//左儿子被占
                    int t=s[i].l;
                    while(s[t].r)//一直刷到右儿子为空
                        t=s[t].r;
                    s[t].r=j;//把这个节点加进去
                    s[j].fa=t;//更新
                }
    sl();//处理森林
    for(int i=1;i<=n;i++)
        pr(s[i].fa),putchar('\n');//依次输出每个节点的父亲编号
}

大概就是这个样子了,欢迎大家来讨论哟!!!

觉得好的话请点个赞吧 :-)

更多我的博客请看这里哟

当然还要谢谢青天璇大佬提供的帮助哟,里面更有详解 ( * ^ - ^ * )!!!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值