uva548-树

此题来自白书数据结构基础二叉树的训练参考

翻译请戳  http://luckycat.kshs.kh.edu.tw/

uva的翻译幸运猫里大部分有

解题思路

建树的思想跟白书里的是一样的,虽然此题给的是中序和后序遍历。

虽然节点最多有10000个,递归建树可能会栈溢出。。。但是依然AC了。。。

最后BFS整棵树就行啦。

代码

#include<stdio.h>
#define MAX_SIZE 10001
//#define LOCAL
typedef struct node {
    int value, tot;
    struct node *lchild, *rchild;
}Node;
int LOrder[MAX_SIZE], pL;
int MOrder[MAX_SIZE], pM;
Node *q[MAX_SIZE];
//char s[1000001];
bool ReadS()
{
    char ch;
    while((ch=getchar())==‘ ‘) ;
    if(ch==EOF) return false;
    while(ch != ‘\n‘) {
        ungetc(ch, stdin);
        int d;
        scanf("%d", &d);
        MOrder[++pM] = d;
        while((ch=getchar())==‘ ‘) ;
    }
    ch = getchar();
//    while(ch==‘ ‘) ch = getchar();
    while(ch != ‘\n‘) {
        ungetc(ch, stdin);
        int d;
        scanf("%d", &d);
        LOrder[++pL] = d;
        while((ch=getchar())==‘ ‘) ;
    }
    return true;
}
int FindRoot(int l, int r)
{
    for(int i=l; i<=r; i++) if(MOrder[i] == LOrder[pL]) return i;
}
void NewNode(Node *&root, int i)
{
    root = new Node;
    root->value = MOrder[i];
    root->tot = root->value;
    root->lchild = root->rchild = NULL;
}
void Build(Node *&root, int l, int r)
{
    if(l>r) { root = NULL; pL++; return ; }
    int i=FindRoot(l, r);
    NewNode(root, i);
    pL--;
    Build(root->rchild, i+1, r);
    pL--;
    Build(root->lchild, l, i-1);
}
void BFS(Node *root)
{
    int front, rear;
    Node* minNode;
    int minTot = 1e9;
    front = rear = MAX_SIZE - 1;
    rear = (rear+1) % MAX_SIZE;
    q[rear] = root;
    while(rear != front) {
        front=(front+1)%MAX_SIZE;
        if(q[front]->lchild != NULL) {
            rear=(rear+1)%MAX_SIZE;
            q[rear] = q[front]->lchild;
            q[rear]->tot += q[front]->tot;
            if(q[rear]->lchild==NULL&&q[rear]->rchild==NULL)
                if(q[rear]->tot < minTot)
                    { minNode = q[rear]; minTot = minNode->tot; }
        }
        if(q[front]->rchild != NULL) {
            rear=(rear+1)%MAX_SIZE;
            q[rear] = q[front]->rchild;
            q[rear]->tot += q[front]->tot;
            if(q[rear]->lchild==NULL&&q[rear]->rchild==NULL)
                if(q[rear]->tot < minTot)
                    { minNode = q[rear]; minTot = minNode->tot; }
        }
        if(q[front]->lchild==NULL&&q[front]->rchild==NULL&&q[front]->tot<minTot)
            { minNode = q[front]; minTot = minNode->tot; }
    }
    printf("%d\n", minNode->value);
}
int main()
{
    #ifdef LOCAL
        freopen("data.txt", "r", stdin);
        freopen("ans.txt", "w", stdout);
    #endif
    while(ReadS()) {
        Node *root = NULL;
        Build(root, 1, pL);
        BFS(root);
        pM = pL = 0;
    }
    return 0;
}
时间: 2024-10-06 02:51:50

uva548-树的相关文章

例题6-8 树 UVa548

1.题目描述:点击打开链接 2.解题思路:本题给出了一颗二叉树的中序遍历和后序遍历,要求找一个叶子,使得它到达根结点的权和最小,如果有多解,那么该叶子自身的权应该尽量小.首先,根据中序遍历和后序遍历建立二叉树,这道题采用数组来存放左右子树的结点值,根为root的左子树结点为lch[root]右子树结点为rch[root]. 那么,如何根据中序遍历,后序遍历来建树呢?方法是根据后序遍历找到根,然后在中序遍历中找到树根,从而找出了左右子树的结点列表,然后递归构造左右子树即可.最后利用先序遍历来求解最

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

【树4】二叉树的遍历

简介 遍历二叉树就是按照某种顺序,将树中的结点都枚举一遍,且每个结点仅仅访问一次.因为树不是线性的结构,遍历不像线性表那样简单,因此他的遍历需要特点的算法来完成. 从某种角度讲,对二叉树的遍历就是将树形结构转换为线性结构的操作. 二叉树的遍历方法主要有如下几种: 先序遍历:先访问root结点,再先序遍历左子树,再先序遍历右子树. 中序遍历:先中序遍历左子树,再访问root结点,再中序遍历右子树. 后序遍历:先后序遍历左子树,再后序遍历右子树,再访问root结点. 层遍历:从上到下,从左到右,一层

关于左偏树的一些东东

大概所有的预备知识这里都有https://baike.baidu.com/item/%E5%B7%A6%E5%81%8F%E6%A0%91/2181887?fr=aladdin 例题1:洛谷 P3377 [模板]左偏树(可并堆) 383通过 1.2K提交 题目提供者HansBug 站长团 标签 难度提高+/省选- 时空限制1s / 128MB 提交 讨论 题解 最新讨论更多讨论 加了路径压缩就WA,路过dal… 左偏树用指针写会MLE吗..… m,n写反了也可以过,数据有… 哪位大神有pbds库

ZJOI 2008 树的统计

ZJOI2008 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身 输入输出格式 输入格式: 输入文件的第一行为一个整数n,表示节点的个数. 接下来n – 1行,每行2个整数

luoguP2590 [ZJOI2008]树的统计 [树链剖分] [TLE的LCT]

题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身 输入输出格式 输入格式: 输入文件的第一行为一个整数n,表示节点的个数. 接下来n – 1行,每行2个整数a和b,表示节点a和节点b之

(POJ 3067) Japan (慢慢熟悉的树状数组)

Japan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29295   Accepted: 7902 Description Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Japan is tall island with N cities on the East coas

[poj2104]可持久化线段树入门题(主席树)

解题关键:离线求区间第k小,主席树的经典裸题: 对主席树的理解:主席树维护的是一段序列中某个数字出现的次数,所以需要预先离散化,最好使用vector的erase和unique函数,很方便:如果求整段序列的第k小,我们会想到离散化二分和线段树的做法, 而主席树只是保存了序列的前缀和,排序之后,对序列的前缀分别做线段树,具有差分的性质,因此可以求任意区间的第k小,如果主席树维护索引,只需要求出某个数字在主席树中的位置,即为sort之后v中的索引:若要求第k大,建树时反向排序即可 1 #include

【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,Lca只是他的一种应用,他可以搞各种树上问题,树上倍增一般都会用到f数组. |||.我们跑出来dfs序就能在他的上面进行主席树了. IV.别忘了离散. V.他可能不连通,我一开始想到了,但是我觉得出题人可能会是好(S)人(B),但是...... #include <cstdio> #include