• POJ 2513 Colored Sticks


    /* 此题考察 并查集 和 hash (或trie树)应用,我是用的hash,可以证明:如果满足题意要求,那么同种颜色出现次数为奇数次的个数不超过2,即最多有两种颜色他们出现的次数为奇数,并且所有的颜色属于同一集,根据这个原理,便有了hash+并查集的算法。这样不怎么费时,510ms就过了。

    在并查集 中,最父节点的值为负值,其绝对值是整个子树节点的个数
    */

    #include<iostream>
    using namespace std;
    int color[500002],set[500002];
    int Hash(char * str)
    {
        
    int hash = 1;
        
    while(*str)
            hash 
    = (hash*29 + *str++ - 'a')%9991;
        
    return hash;
    }
    int find_set(int x)
    {
        
    int tmp=0;
        
    int root=x;
        
    while(set[root]>=0)
        {
            root
    =set[root];
        }
        
    while(x!=root)
        {
            tmp
    =set[x];
            
    set[x]=root;
            x
    =tmp;
        }
        
    return root;
    }
    void union_set(int root1,int root2)
    {
        
    int sum = set[root1]+set[root2];
        
    if(set[root1]>set[root2])
        {
            
    set[root1] = root2;
            
    set[root2] = sum;
        }
        
    else
        {
            
    set[root2] = root1;
            
    set[root1] = sum;
        }
    }
    int main()
    {
        
    int n1,n2,n=0,root1,root2,i,no=0;
        
    char a[11],b[11];
        
    for(i=0;i<500002;++i)
        {
            
    set[i]=-1;
            color[i]
    =0;
        }
        
    while(scanf("%s%s",a,b)!=EOF)
        {
            
    ++n;
            n1
    =Hash(a);
            n2
    =Hash(b);
            
    ++color[n1];
            
    ++color[n2];
            root1
    =find_set(n1);
            root2
    =find_set(n2);
            
    if(root1!=root2)
                union_set(root1,root2);
        }
        
    int root=1;
        
    for(int i=0;i<500002;++i)
        {
            
    if(color[i]>0)
            {
                
    if(color[i]%2)
                {
                    
    ++no;
                    
    if(no>2)
                    {
                         printf(
    "Impossible\n");
                        
    return 0;
                    }
                }
                
    if(root==1)
                    root 
    = find_set(i);
                
    else
                    
    if(root!=find_set(i)){ printf ("Impossible\n");return 0;}
            }
        }
         printf(
    "Possible\n");
        
    return 0;
    }


  • 相关阅读:
    js 数组详解(javascript array)
    CentOS 修改IP地址, DNS, 网关
    Leetcode 652.寻找重复的子树
    Leetcode 650.只有两个键的键盘
    Leetcode 649.Dota2参议院
    Leetcode 648.单词替换
    Leetcode 647.回文子串
    Leetcode 645.最长数对链
    Leetcode 643.子数组最大平均数I
    Leetcode 640.求解方程
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1662787.html
Copyright © 2020-2023  润新知