posts - 13, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

POJ 2513 Colored Sticks

Posted on 2009-04-22 14:49 杜仲当归 阅读(452) 评论(0)  编辑 收藏 引用

主要考查的是对并查集的运用,其次必须使用字典树,STL的map会超时。

模板题,不用动脑子。并查集判是否连通,欧拉回路判度数,字典树做map的工作。为了解题方便,特意写了个UFSets类。做完之后发现不用类的时间效率高出现在很多,大概主要时间都浪费在调用类函数上了……很多事都是这样,若是不仔细考虑,没有通盘规划,看上去与人方便,实际上平添事端。

/*
类调用函数效率不高,应直接用数组为宜
*/


#include 
<iostream>
#include 
<string>
using namespace std;

#define MAX 500001

// 并查集
class UFSets
{
private:
    
int size;
    
int *parent, *rank;
public:
    UFSets ();
    
~UFSets () { delete []parent; }
    
void Union ( int root1, int root2 );
    
int Find ( int x );
}
;
UFSets::UFSets ()
{
    size 
= MAX;
    parent 
= new int[size + 1];
    rank 
= new int[size + 1];
    
int i;
    
for ( i = 0; i <= size; i ++ )
        parent[i] 
= -1;
    
for ( i = 0; i <= size; i ++ )
        rank[i] 
= 1;

}

int UFSets::Find ( int x )
{
    
if ( parent[x] < 0 || parent[x] == x )
        
return parent[x] = x;
    
else
        
return parent[x] = Find ( parent[x] );
}

void UFSets::Union ( int root1, int root2 )
{
    
if ( rank[root1] < rank[root2] )
    
{
        rank[root2] 
+= rank[root1];
        parent[root1] 
= root2;
    }

    
else
    
{
        rank[root1] 
+= rank[root2];
        parent[root2] 
= root1;
    }

}


// 字典树
struct TrieTree
{
    TrieTree 
*next[26];
    
int id;
}
;
TrieTree 
*Root;

void init ()
{
    Root 
= new TrieTree;
    
int i;
    
for ( i = 0; i < 26; i ++ )
        Root
->next[i] = NULL;
    Root
->id = 0;
}


int search ( char s[] )
{
    
int i, len = strlen ( s );
    TrieTree 
*p, *t;
    p 
= Root;
    
for ( i = 0; i < len; i ++ )
    
{
        
if ( p->next[s[i] - 'a'== NULL )
        
{
            t 
= new TrieTree;
            
int j;
            
for ( j = 0; j < 26; j ++ )
                t
->next[j] = NULL;
            t
->id = 0;
            p
->next[s[i] - 'a'= t;
        }

        p 
= p->next[s[i] - 'a'];
    }

    
if ( p->id == 0 )
        
return p->id = cnt ++;
    
else
        
return p->id;
}


void del ( TrieTree *p )
{
    
int i;
    
for ( i = 0; i < 26; i ++ )
    
{
        
if ( p->next[i] != NULL )
            del ( p
->next[i] );
    }

    delete p;
}



UFSets u;
char s1[100], s2[100];
int deg[MAX];
int cnt;

bool check1 ()
{
    
int i, def = u.Find ( 1 );
    
//printf ( "%d\n", def );
    for ( i = 2; i < cnt; i ++ )
    
{
        
//printf ( "%d\n", u.Find ( i ) );
        if ( u.Find ( i ) != def )
            
return 0;
    }

    
return 1;
}


bool check2 ()
{
    
int i;
    
int odd = 0;
    
for ( i = 1; i < cnt; i ++ )
        
if ( deg[i] & 1 )
            odd 
++;
    
return odd <= 2;
}


int main ()
{
    
//freopen ( "in.txt", "r", stdin );
    
//freopen ( "out.txt", "w", stdout );
    cnt = 1;
    memset ( deg, 
0sizeof ( deg ) );
    init ();
    
while ( scanf ( "%s %s", s1, s2 ) != EOF )
    
{        
        
int i1 = search ( s1 ), i2 = search ( s2 );
        deg[i1] 
++, deg[i2] ++;
        
int r1 = u.Find ( i1 ), r2 = u.Find ( i2 );
        u.Union ( r1, r2 );
    }

    del ( Root );
    
if ( !check1 () )
    
{
        printf ( 
"Impossible\n" );
        
return 0;
    }

    
if ( !check2 () )
    
{
        printf ( 
"Impossible\n" );
        
return 0;
    }

    printf ( 
"Possible\n" );
    
return 0;
}


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理