zoukankan      html  css  js  c++  java
  • zoj 1097 普吕弗序列

    题目大意:输入一颗无根树的括号序列,求这棵树的普吕弗序列。

    分析思路:

    1)普吕弗序列,可以参考维基百科,其做法是找出树中编号最小的叶子节点,并将此叶子节点及边删除,并输出其邻接的节点标号;

    2)递归地构造树,可以使用list<int> 数组来表示一个“邻接表”,以存储构造的树;

    3)使用优先队列来进行删除,奈何priority_queue没有迭代器访问,只能用堆排序,取最值;

    代码:

    #include<iostream>
    #include<vector>
    #include<map>
    #include<queue>
    #include<string>
    #include<algorithm>
    #include<fstream>
    #include<list>
    using namespace std;
    
    struct nodeAndDegree
    {
        int degree;      //
        int nodeNumber;  //结点编号
        bool operator < (const nodeAndDegree& n1)const
        {
            return  degree == n1.degree ? (nodeNumber > n1.nodeNumber) : (degree > n1.degree);
        }
    };
    
    const int MAX_LEN = 55;
    list<int> vGraph[MAX_LEN];
    vector<int> v;
    int rootNumber = 0;
    
    void dfs(int start, int end, int parent, string str)
    {
        if (start == end)  //只有单个点
        {
            return;
        }
    
        //放入邻接矩阵
        int currentNode = 0;
        for (int i = start + 1; i <= end - 1; i++)
        {
            if (str[i] == ' ' || str[i] == '' || str[i] == '(')
            {
                break;
            }
            currentNode = currentNode * 10 + (int)(str[i] - 48);
        }
    
        //放入邻接矩阵
        vGraph[parent].push_back(currentNode);
        vGraph[currentNode].push_back(parent);
        v.push_back(currentNode);
    
        int mark = 0;
        int tmpStart = -1;
        for (int i = start + 1; i <= end - 1; i++)
        {
            if (str[i] == '(')
            {
                mark++;
                if (tmpStart == -1) tmpStart = i;
                continue;
            }
    
            if (str[i] == ')')
            {
                mark--;
                if (mark == 0)
                {
                    dfs(tmpStart, i, currentNode, str);
                    tmpStart = -1;
                }
            }
        }
    }
    
    void print_prufer_sequnce()
    {
        //首先修改根节点对应的长度
        int tmp = vGraph[0].front();
        vGraph[tmp].remove(0);
    
        vector<nodeAndDegree> listNodeDegree;
        for (int i = 0; i < v.size(); i++)
        {
            nodeAndDegree *nd = new nodeAndDegree();
            nd->nodeNumber = v[i];
            nd->degree = vGraph[v[i]].size();
    
            listNodeDegree.push_back(*nd);
        }
    
        int n = v.size() - 1;
        int index = 0;
    
        while (index < n)
        {
            make_heap(listNodeDegree.begin(), listNodeDegree.end());
            int number = listNodeDegree[0].nodeNumber;  //当前结点
            int front = vGraph[number].front();
    
            cout << front ;
            if (index != n - 1)
            {
                cout << " ";
            }
            vGraph[front].remove(number);
            vGraph[number].remove(front);
            for (int j = 1; j < listNodeDegree.size(); j++)
            {
                if (listNodeDegree[j].nodeNumber == front)
                {
                    listNodeDegree[j].degree--;
                    break;
                }
            }
    
            listNodeDegree.erase(listNodeDegree.begin());
    
            index++;
        }
    }
    
    int main()
    {
        string s;
        //fstream cin("1097.txt");
        while (getline(cin, s))
        {
            for (int i = 0; i < MAX_LEN; i++)
            {
                vGraph[i].clear();
            }
            v.clear();
            dfs(0, s.size() - 1, 0, s);
            print_prufer_sequnce();
            cout << endl;
        }
        return 0;
    }

    以纪念我那逝去的耗费精力的兴奋的AC。

  • 相关阅读:
    POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)
    UVaLive 5031 Graph and Queries (Treap)
    Uva 11996 Jewel Magic (Splay)
    HYSBZ
    POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)
    HDU 1890 Robotic Sort (Splay 区间翻转)
    【转】ACM中java的使用
    HDU 4267 A Simple Problem with Integers (树状数组)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4417 Super Mario (树状数组/线段树)
  • 原文地址:https://www.cnblogs.com/pengzhen/p/4375827.html
Copyright © 2011-2022 走看看