左儿子右兄弟表示法

顾名思义

每个节点一个为儿子指针,一个为兄弟指针(在加个父亲)

这样就避免了儿子个数不均带来的问题

TOJ   TOJ4077

用一个指针记录当前在哪个节点,需要注意的是可以有多个重名的文件,但是不能在一个目录下。

所以用文件名和其父亲节点作为一个文件的id(区分其他)。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>

using namespace std;

typedef long long LL;

const int N=100100;
char ma[N][20];
int mma[N];
char ans[N][20];
struct node {
    int son,fa;
    int bro;
}root,a[N];
int cnt;
int cur;
void add(int x,char *s){
    strcpy(ma[cnt],s);
    mma[cnt]=x;
    int p=a[x].son;
    a[cnt].bro=-1;
    a[cnt].fa=x;
    a[cnt].son=-1;
    if(p==-1){
        a[x].son=cnt;
    }
    else{
        while(a[p].bro!=-1)p=a[p].bro;
        a[p].bro=cnt;
    }
    cnt++;
}
void dele(int x,int y){
    int p=a[x].son;
    if(p==-1)return;
    if(p==y){
        a[x].son=a[p].bro;
    }
    else{
        while(p!=-1&&a[p].bro!=y)p=a[p].bro;
        if(p==-1)return;
        a[p].bro=a[a[p].bro].bro;
        return;
    }
}
void init(){
    a[0].fa=-1;
    a[0].son=-1;
    a[0].bro=-1;

    cnt=1;
    add(0,"home");
    add(1,"brotherkai");
    cur=2;
}
int fin(int x,char str[]){
    for(int i=0;i<cnt;i++){
        if(strcmp(ma[i],str)==0&&mma[i]==x){
            return i;
        }
    }
    return -1;
}
int r[N];
int cmp(int a,int b){
    if(strcmp(ans[a],ans[b])<=0)return 1;
    return 0;
}
void dfs(int x){
    mma[x]=-1;
    for(int i=a[x].son;i!=-1;i=a[i].bro){
        dfs(i);
    }
    return;
}
void solve(char str[]){
    char op1[50],op2[50];
    if(str[0]==‘l‘){
        int nu=0;
        for(int i=a[cur].son;i!=-1;i=a[i].bro){
            strcpy(ans[nu++],ma[i]);
        }
        for(int i=0;i<nu;i++)r[i]=i;
        if(nu){
            sort(r,r+nu,cmp);
            printf("%s",ans[r[0]]);
            for(int i=1;i<nu;i++){
                printf(" %s",ans[r[i]]);
            }

        }
        printf("\n");
    }
    else if(str[0]==‘c‘){
        scanf("%s",op1);
        if(op1[0]==‘/‘){
            cur=0;
        }else if(op1[0]==‘.‘){
            if(cur!=0)
                cur=a[cur].fa;
        }
        else{
            int x=fin(cur,op1);
            if(x==-1)return;
            cur=x;
        }
    }
    else if(str[0]==‘r‘){
        scanf("%s%s",op2,op1);
        int x=fin(cur,op1);
        if(x==-1)return;
        else{
            mma[x]=-1;
            dfs(x);
            dele(cur,x);
        }
    }
    else if(str[0]==‘m‘){
        scanf("%s",op1);
        int x=fin(cur,op1);
        if(x==-1){
            add(cur,op1);
        }
    }
    return;

}

int main()
{

    char str[30];
    init();
    while(scanf("%s",str),str[0]!=‘e‘){

        solve(str);

    }
    return 0;
}

左儿子右兄弟表示法

时间: 2024-10-11 16:38:02

左儿子右兄弟表示法的相关文章

UVa 11732 &quot;strcmp()&quot; Anyone? (左儿子右兄弟前缀树Trie)

题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832 字符串很多,又很长,如果按照题目的意思两两比较,肯定会TLE,所以要用前缀树(Trie)来解决,当然只是用简单的前缀树也会TLE的, 我们必须对其进行优化,看了

左儿子右兄弟Trie UVA 11732 strcmp() Anyone?

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. 分析: 大白上的题目. 听说要用左儿子右兄弟的Trie,比较省空间,顺便学了下. 一边inser

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie)

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. 分析: 大白上的题目. 听说要用左儿子右兄弟的Trie,比较省空间,顺便学了下. 开始先建树记录次数,然后再遍历统计,结果错了... 后面参考了Shoutmon巨巨的写法,一边insert一边统计. 代码: /* * Author: illuz <iilluzen[at]gmail.com> *

任意有根树的左孩子右兄弟表示法存储

算法导论:10.4-4 对一个含n个结点的任意有根树,写出一个O(n)时间的过程,输出其所有关键字. 该树以左孩子或兄弟表示法存储. #ifndef _ROOTED_TREE_H_ #define _ROOTED_TREE_H_ /***************************************************************** 算法导论:10.4-4 对一个含n个结点的任意有根树,写出一个O(n)时间的过程,输出其所有关键字. 该树以左孩子或兄弟表示法存储. *

UVa 11732 strcmp()函数(左孩子右兄弟表示法)

1 #include<iostream> 2 #include<algorithm> 3 #include<string> 4 #include<cstring> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 4000 * 1000 + 10; 9 int n; 10 long long ans; 11 12 struct Trie 13 { 14 int head[

UVA11732 &quot;strcmp()&quot; Anyone?【左儿子右兄弟Trie】

LINK1 LINK2 题目大意 给你一些字符串,并定义了一个函数(具体见题面) 问你把任意两个字符串放到函数里面得到的值的和是多少 思路 该怎么统计答案呢? 每次考虑当前插入的串和所有已经插入过的串一起统计答案 然后考虑一下怎么统计,假设当前深度是dep 并且现在是u,即将向v移动指针 那么怎么同几当前这一层的答案呢? 所有在v的子树中的节点显然是不能在这一层统计答案的 所以就考虑统计和所有不在同一个子树的答案 具体实现很简单,读者自己思考吧 注意在每一次走到字符串的末尾的时候需要特判 和他相

Vijos p1518 河流 转二叉树左儿子又兄弟

左儿子又兄弟的转发一定要掌握啊,竞赛必用,主要是降低编程复杂度,省时间.个人觉得状压DP也是为了降低编程复杂度. 方程就不说了,程序应该能看得懂,用的记忆化搜索,方便理解. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 bool p[103]; 6 int N,K,point[103],next[203],v[203],c[203],w[103]

《数据结构》示范程序\树的长子-兄弟表示法

/* 树的长子-兄弟表示法*/ #include<stdio.h> typedef int DataType ; struct CSNode; /* 树中结点结构 */ typedef struct CSNode *PCSNode; /* 结点的指针类型 */ struct CSNode /* 结点结构定义 */ { DataType info; /* 结点中的元素 */ PCSNode lchild; /* 结点的最左子女的指针 */ PCSNode rsibling; /* 结点的右兄弟的

在一个二维数组中,每一行都按照从左到右递增的顺序排序

/*  * 在一个二维数组中,  * 每一行都按照从左到右递增的顺序排序,  * 每一列都按照从上到下递增的顺序排序.  * 请完成一个函数,输入这样的一个二维数组和一个整数,  * 判断数组中是否含有该整数.  */ public static void main(String[] args) { int[][] array = {{1,2,3},{4,5,6},{7,8,9}}; System.out.println(Find2(1, array)); } /*  * 思路一:暴力遍历法