我叫张小黑
张小黑的挣扎生活
posts - 66,  comments - 109,  trackbacks - 0
http://acm.pku.edu.cn/JudgeOnline/problem?id=2513
这道题是直接拿前几天写得模版改的;做了几个修改
首先删掉了search,这道题的确不需要,本来没删,代码实在太长,逼得我没办法
第二个,把trie中num[]的意思改掉了,num[]现在存的是字符串在一个数组的标记,
相当于map的实现,通过这样我把一个字符串和一个标号对应上了,方便了并查集的操作
果然很久没碰并查集了,一写就出问题,
主要是我union_set是居然忘了要先find_set一下,这样写针对下面这组数据就会出现问题:
a b
b a
a a
还有一个就是这道题的空输入问题,要输出possible,而不是Impossible
一下是我的垃圾代码,跑了500多,有谁有更好的发我邮箱哈: zhangjia888334@sohu.com
#include<iostream>
#include
<cstring>
#define keyNum 
26
#define MaxN 
500005
struct node{
    
int parent;
    
int rank;
    
int num;//这个颜色出现的次数
    node()
    {
        num
=rank=0;
        parent
=-1;
    }
};
node colour[MaxN];
int id=0;//数组标记
struct trie{
    struct trieNode{
//trie结点的结构
    trieNode 
*link[keyNum];//下标为 'a' , 'b' , 'c' ,  , 'z' 的指针数组
    int num[keyNum];//插入这个单词在数组中的位置
    trieNode(){
        memset(num,
-1,sizeof(num));//-1表示还未插入数组
        memset(link,
NULL,sizeof(link));
        }
    void init(){
        memset(link,
NULL,sizeof(link));
        memset(num,
-1,sizeof(num));
    }
    };
    trieNode
* root;
    trie()
    {
        root
=(trieNode*)malloc(sizeof(trieNode));//初始化时为root申请了空间
        root
->init();
    }
    
int Insert(char []);//返回数组中的位置
    void Delete(trieNode
*);//释放空间
};
void trie::Delete(trieNode
* t)
{
    
int i;
    
for(i=0;i<keyNum;i++)
        
if(t->link[i])Delete(t->link[i]);
    memset(t
->num,0,sizeof(t->num));
    delete(t);
}
int trie::Insert(char x[])
{
    trieNode 
*current=root;
    
int i=1;
    
while(x[i]){
        
if(current->link[x[i-1]-'a']==NULL){
            current->link[x[i-1]-'a']=(trieNode*)malloc(sizeof(trieNode));
            (current->link[x[i-1]-'a'])->init();
        }
        current
=current->link[x[i-1]-'a'];
        i++;
    }
    
if(current->num[x[i-1]-'a']==-1)
        current->num[x[i-1]-'a']=id++;
    colour[current->num[x[i-1]-'a']].num++;//出现的次数++
    return current->num[x[i-1]-'a'];
}
void init()
{
    
int i;
    
for(i=0;i<MaxN;i++)
        colour[i].parent
=i;
}
void union_set(
int x,int y)
{
    
if(colour[x].rank>colour[y].rank)
        colour[y].parent
=x;
    
else {
        colour[x].parent
=y;
        
if(colour[x].rank==colour[y].rank)
            colour[y].rank
++;
    }
}
int find_set(int x)
{
    
if(x!=colour[x].parent)
        colour[x].parent
=find_set(colour[x].parent);
    return colour[x].parent;
}
bool comman_father()
{
    
int i,p=0;
    p
=find_set(0);
    
for(i=1;i<id;i++)
        
if(find_set(i)!=p)return false;
    return 
true;
}
void solve()
{
    
if(comman_father()==false){
        printf(
"Impossible\n");
        return;
    }
    
int i,head_end=0;
    
for(i=0;i<id;i++)
        
if(colour[i].num%2==1)//判断头和尾
            head_end
++;
    
if(head_end==2||!head_end)//一个没回路,一个是有回路
        printf(
"Possible\n");
    
else printf("Impossible\n");
}
int main()
{
    char colr1[
12],colr2[12];
    trie a;
    
int ncolr1,ncolr2;
    init();
    
while(scanf("%s%s",colr1,colr2)!=EOF){
        ncolr1
=a.Insert(colr1);
        ncolr2
=a.Insert(colr2);
        union_set(find_set(ncolr1),find_set(ncolr2));
    }
    
//下面判断有几个parent,若有多个失败
    solve();
    a.Delete(a.root);
    return 
0
}
posted on 2008-04-08 18:35 zoyi 阅读(860) 评论(1)  编辑 收藏 引用 所属分类: acm数据结构

FeedBack:
# re: trie树+并查集
2008-04-08 19:41 | arena_zp
不知道为什么,
我的始终在 1300 + 。。
莫名~~~~~  回复  更多评论
  

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


欢迎光临 我的白菜菜园

<2008年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿(8)

随笔分类

随笔档案

文章档案

相册

acmer

online judge

队友

技术

朋友

搜索

  •  

最新评论

阅读排行榜

评论排行榜