• 第五讲 树(下)


    05-树7:堆中的路径
    Description:

    将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。

    Input:

    每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。

    Output:

    对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。

    SampleInput:

    5 3
    46 23 26 24 10
    5 4 3

    SampleOutput:

    24 23 10
    46 23 10
    26 10

    Codes:
    //#define LOCAL
    
    #include <cstdio>
    
    #define M 1010
    #define S -10010
    int i, cnt, A[M] = {S};
    
    void insert(int a) {
        for(i=++cnt; A[i/2]>a; i/=2) A[i] = A[i/2];
        A[i] = a;
    }
    
    int main()
    {
        #ifdef LOCAL
            freopen("E:\Temp\input.txt", "r", stdin);
            freopen("E:\Temp\output.txt", "w", stdout);
        #endif
    
        int a, n, m;
        scanf("%d%d", &n, &m);
    
        while(n--) { scanf("%d", &a); insert(a); }
        while(m--) {
            scanf("%d", &a);
            printf("%d", A[a]); a /= 2;
            while(a) { printf(" %d", A[a]); a /= 2; } 
            printf("
    "); 
        }
    
        return 0;
    }
    
    05-树8:File Transfer.
    Description:

    We have a network of computers and a list of bi-directional connections. Each of these connections allows a file transfer from one computer to another. Is it possible to send a file from any computer on the network to any other?

    Input:

    Each input file contains one test case. For each test case, the first line contains N(2, 10^4), the total number of computers in a network. Each computer in the network is then represented by a positive integer between 1 and N. Then in the following lines, the input is given in the format: I c1 c2 where I stands for inputting a connection between c1 and c2; or C c1 c2 where C stands for checking if it is possible to transfer files between c1 and c2; or S where S stands for stopping this case.

    Output:

    For each C case, print in one line the word "yes" or "no" if it is possible or impossible to transfer files between c1 and c2, respectively. At the end of each case, print in one line "The network is connected." if there is a path between any pair of computers; or "There are k components." where k is the number of connected components in this network.

    SampleInput1:

    5
    C 3 2
    I 3 2
    C 1 5
    I 4 5
    I 2 4
    C 3 5
    S

    SampleOutput1:

    no
    no
    yes
    There are 2 components.

    SampleInput2:

    5
    C 3 2
    I 3 2
    C 1 5
    I 4 5
    I 2 4
    C 3 5
    I 1 3
    C 1 5
    S

    SampleOutput2:

    no
    no
    yes
    yes
    The network is connected.

    Codes:
    //#define LOCAL
    
    #include <cstdio>
    #include <cstdlib>
    
    int findS(int *s, int v) {
        while(s[v] >= 0) v = s[v];
        return v;
    }
    
    void unionS(int *s, int c1, int c2) {
        int r1 = findS(s, c1), r2 = findS(s, c2);
        if(s[r1] < s[r2]) { s[r1] += s[r2]; s[r2] = r1; }
        else { s[r2] += s[r1]; s[r1] = r2; }
    }
    
    int main()
    {
        #ifdef LOCAL
            freopen("E:\Temp\input.txt", "r", stdin);
            freopen("E:\Temp\output.txt", "w", stdout);
        #endif
    
        int i, n, c1, c2, cnt = 0; char c;
        scanf("%d
    %c", &n, &c);
        
        int *s = (int*)malloc(sizeof(int)*(n+1));
        for(i=0; i<=n; ++i) s[i] = -1;
        while(c != 'S') {
            scanf("%d%d", &c1, &c2);
            if(c == 'I') unionS(s, c1, c2);
            else if(c == 'C') {
                if(findS(s, c1) == findS(s, c2)) printf("yes
    ");
                else printf("no
    ");
            }
            scanf("
    %c", &c);
        }
    
        for(i=1; i<=n; ++i) if(s[i] < 0) ++cnt;
        if(cnt == 1) printf("The network is connected.
    ");
        else printf("There are %d components.
    ", cnt);
        free(s);
    
        return 0;
    }
    
    05-树9:Huffman Codes.
    Description:

    In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redundancy Codes", and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes, I am encountering a big problem: the Huffman codes are NOT unique. For example, given a string "aaaxuaxz", we can observe that the frequencies of the characters 'a', 'x', 'u' and 'z' are 4, 2, 1 and 1, respectively. We may either encode the symbols as {'a'=0, 'x'=10, 'u'=110, 'z'=111}, or in another way as {'a'=1, 'x'=01, 'u'=001, 'z'=000}, both compress the string into 14 bits. Another set of code can be given as {'a'=0, 'x'=11, 'u'=100, 'z'=101}, but {'a'=0, 'x'=01, 'u'=011, 'z'=001} is NOT correct since "aaaxuaxz" and "aazuaxax" can both be decoded from the code 00001011001001. The students are submitting all kinds of codes, and I need a computer program to help me determine which ones are correct and which ones are not.

    Input:

    Each input file contains one test case. For each case, the first line gives an integer N (2, 63), then followed by a line that contains all the N distinct characters and their frequencies in the following format: c[1] f[1] c[2] f[2] ... c[N] f[N] where c[i] is a character chosen from {'0' - '9', 'a' - 'z', 'A' - 'Z', '_'}, and f[i] is the frequency of c[i] and is an integer no more than 1000. The next line gives a positive integer M (≤1000), then followed by M student submissions. Each student submission consists of N lines, each in the format: c[i] code[i] where c[i] is the i-th character and code[i] is an non-empty string of no more than 63 '0's and '1's.

    Output:

    For each test case, print in each line either "Yes" if the student's submission is correct, or "No" if not.

    Note: The optimal solution is not necessarily generated by Huffman algorithm. Any prefix code with code length being optimal is considered correct.

    SampleInput:

    7
    A 1 B 1 C 1 D 3 E 3 F 6 G 6
    4
    A 00000
    B 00001
    C 0001
    D 001
    E 01
    F 10
    G 11
    A 01010
    B 01011
    C 0100
    D 011
    E 10
    F 11
    G 00
    A 000
    B 001
    C 010
    D 011
    E 100
    F 101
    G 110
    A 00000
    B 00001
    C 0001
    D 001
    E 00
    F 10
    G 11

    SampleOutput:

    Yes
    Yes
    No
    No

    Codes:
    #include <iostream>
    #include <vector>
    #include <string>
    using namespace std;
    
    class HuffmanTree {
        struct Node {
            Node(int w = 0):weight(w), left(NULL), right(NULL), parent(NULL) {}
            int weight; Node *left, *right, *parent;
        };
    
        class MinHeap {
        public:
            MinHeap(int N) {
                cbtree = new Node*[N+1];
                cbtree[0] = new Node(-1);
                size = 0;
            };
            ~MinHeap() {
                delete cbtree[0];
                cbtree[0] = NULL;
                delete[] cbtree;
            }
            int Size() { return size; }
            void Insert(Node *item) {
                int i = ++size;
                for (; item->weight<cbtree[i/2]->weight; i/=2) cbtree[i] = cbtree[i/2];
                cbtree[i] = item; return;
            }
    
            Node* DeleteMin() {
                Node *min_node = cbtree[1];
                Node *last_node = cbtree[size];
                cbtree[size--] = NULL;
                int child, parant = 1;
                while (parant*2 <= size) {
                    child = 2*parant;
                    if (child!=size && cbtree[child+1]->weight<cbtree[child]->weight) ++child;
                    if (last_node->weight < cbtree[child]->weight) break;
                    else cbtree[parant] = cbtree[child];
                    parant = child;
                }
                cbtree[parant] = last_node;
                return min_node;
            }
    
        private:
            Node* *cbtree; int size; };
    public:
        HuffmanTree(int capacity):heap(capacity), root(NULL), leaves(0), wpl(0) {}
        ~HuffmanTree() {
            for (size_t i=0; i<nodes.size(); ++i) delete nodes[i];
        }
        void Insert(int item) {
            ++leaves;
            nodes.push_back(new Node(item));
            heap.Insert(nodes.back());
        }
        int GetWeight(int leave) { return nodes[leave]->weight; }
        int GetWPL() {
            if (!root) Build();
            if (!wpl) {
                for (int i=0; i<leaves; ++i) {
                    int depth = 0;
                    for (Node *leave=nodes[i]; leave->parent; leave=leave->parent) ++depth;
                    wpl += depth*nodes[i]->weight;
                }
            }
            return wpl;
        }
    private:
        Node *NextEmptyNode() {
            static int next = leaves;
            ++next; nodes[next] = new Node();
            return nodes[next];
        }
        void Build() {
            if (!root) {
                nodes.resize(2*leaves-1);
                for (int i=0; i<leaves-1; ++i) {
                    Node *merged = NextEmptyNode();
                    merged->left = heap.DeleteMin();
                    merged->right = heap.DeleteMin();
                    merged->weight = merged->right->weight+merged->right->weight;
                    merged->right->parent = merged->left->parent = merged;
                    heap.Insert(merged);
                }
                root = heap.DeleteMin();
            }
        }
    private:
        MinHeap heap; Node *root;
        int leaves, wpl;
        vector<Node*> nodes;
    };
    bool IsPrefixConflict(string codes[], int N) {
        for (size_t i=0; i<N; ++i) {
            for (size_t j=0; j!=i &&j<N; ++j) 
                if(!codes[j].find(codes[i])) return true;
        }
        return false;
    }
    
    int main() {
    
        int i, f, N, M; char c;
        cin >> N;
        HuffmanTree tree(N);
        for (i=0; i<N; ++i) { cin >> c >> f; tree.Insert(f); }
        cin >> M;
        
        for (size_t mstu=0 ; mstu<M; ++mstu) {
            string codes[64];
            for (size_t ncode=0; ncode<N; ++ncode) cin >> c >> codes[ncode];
            int wpl = 0;
            for (int kcode=0; kcode<N; ++kcode) wpl += (codes[kcode].length()*tree.GetWeight(kcode));
            if (!IsPrefixConflict(codes, N)&&wpl == tree.GetWPL()) cout << "Yes" << endl;
             else cout << "No" << endl;
        }
    
        return 0;
    }
  • 相关阅读:
    Flutter 路由管理
    SpringMVC 集成 MyBatis
    关于windows下安装mysql数据库出现中文乱码的问题
    md5.digest()与md5.hexdigest()之间的区别及转换
    MongoDB基础命令及操作
    redis相关操作&基本命令使用
    python中mysql主从同步配置的方法
    shell入门基础&常见命令及用法
    ORM总结
    多任务:进程、线程、协程总结及关系
  • 原文地址:https://www.cnblogs.com/VincentValentine/p/6847288.html
Copyright © 2020-2023  润新知