zoukankan      html  css  js  c++  java
  • POJ 2513 (Trie树+欧拉通路+并查集判断连通)

    题目:http://poj.org/problem?id=2513 两个教训: 一、输入输出用scanf、printf(好像自己已经强调很多遍了= =……) eg:用cin 1000MS 用scanf 400MS………… 二、不要把string作为函数值传递参数(推广到整个STL,STL加了很多没用的功能会导致效率变低) eg:此题Trie中的参数用string 4485MS 用char * 985MS………… 题目大意:每个木棒头尾都有两种颜色,木棒末端颜色相同的可以连接成一条直线,问能否将所有木棒连接起来组成一条直线。 题目求解:传换成图的问题就是求解能否一笔画成(欧拉通路) 代码技巧:用数组字典树和链表字典树都可以,动态链表空间少好写,静态数组速度快,看情况吧。  
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    #define N 500005
    
    struct set
    {
        int parent;  //记录父节点
        int rank;    //记录集合的节点数
    }elem[N];
    
    int MAX;
    
    void init()
    {
        int i;
        for(i=0;i<=N;i++)
        {
            elem[i].parent=i;
            elem[i].rank=1;
        }
    }
    
    int Find(int x)
    {
        int root,temp;
        temp=x;
        while(x!=elem[x].parent)    //寻找根节点
            x=elem[x].parent;
        root=x;
        x=temp;
        while (x!=elem[x].parent)   //压缩路径,全部赋值为根节点的值
        {
            temp=elem[x].parent;
            elem[x].parent=root;
            x=temp;
        }
        return root;
    }
    
    void Union(int a,int b)   //合并两个集合
    {
        int x,y;
        x=Find(a);
        y=Find(b);
        if(elem[x].rank>=elem[y].rank)
        {
            elem[y].parent=elem[x].parent;
            elem[x].rank+=elem[y].rank;
            if(MAXnext[word[i]-'a'] == NULL)      //如果不存在的话,我们就建立一个新的节点
            {
                Trie_node *tmp = new Trie_node();
                p->next[word[i]-'a'] = tmp;
                p = p->next[word[i]-'a'];         //每插入一步,相当于有一个新串经过,指针要向下移动
            }
            else                                //如果这个节点之前就已经存在呃,我们只需要把统计次数加上1
                p=p->next[word[i]-'a'];
            //p->Ch_Count++;                      //这里是求所有前缀出现的次数,如果只求整个单词出现次数则用后一个
        }
        //p->Ch_Count++;                              //求整个单词的出现次数
    
        if (p->hash<0)
            p->hash=words_num++;
    
        return p->hash;
    }
    
    Trie t;
    
    
    int main()
    {
        //freopen("test.in","r",stdin);
    
        init();
        char a1[15],a2[15];
        words_num=0;
        while(scanf("%s%s",a1,a2)!=EOF)
        {
            int x,y;
            x=t.insert(a1);
            degree[x]++;
            y=t.insert(a2);
            degree[y]++;
            Union(x,y);
        }
        int sum=0;
        for (int i=0;i2)
            {
                printf("Impossible\n");
                return 0;
            }
        }
    
        for (int i=0;i
     
    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    使用junit进行单元测试
    初学软件工程.
    初学软件工程
    寻医问药软件
    使用JUnit工具进行单元测试
    软件工程问题
    JUnit进行单元测试
    软件工程学习问题
    单元测试
    软件工程
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4113957.html
Copyright © 2011-2022 走看看