http://poj.org/problem?id=1308

题意:给出一些节点的连接情况,问所给出的节点是不是可以构成一棵树。

树的定义已经给出:

1. 只有一个根节点

2. 根节点到每个节点只有唯一路径

3. 题目第一句特别提到空树也是一颗合法树

对于第一条,明显的森林不是树,并查集将每对输入合并,最后看是否在同一个集合中。

第二条,保证唯一路径与题目中给出的第二条定义相似,对于每个节点,只有一条边指向它。如果节点已经存在于集合中,则肯定已经有一边指向它,或者它是作为根节点。也就是说,输入的两个元素不能在同一个集合中。可恶的是这题居然没给数据量!开始以200为上限做的,最后用majia试了下数据范围,竟然只有15。。。太坑了...

code:

#include<cstdio>
int p[16], data[32] ;
void make_set(){
    for(int i=0; i<101; i++)
        p[i] = i ;
}
int find_set(int x){
    if(x!=p[x])
        p[x] = find_set(p[x]) ;
    return p[x] ;
}
void union_set(int x, int y){
    x = find_set(x) ;
    y = find_set(y) ;
    if(x!=y)
        p[y] = x ;
}
int main(){
    int x, y, t=1, count ;
    bool flag ;
    while(~scanf("%d%d", &x, &y)&&(x+y)>=0){
        flag = true ;
        count = 0 ;
        data[count++] = x ;
        data[count++] = y ;
        if(x==0&&y==0){
            printf("Case %d is a tree.\n", t++) ;
            continue ;
        }
        make_set() ;
        if(x==y)    flag = false ;
        union_set(x, y) ;
        while(~scanf("%d%d", &x, &y)&&(x+y)){
            if(find_set(x)==find_set(y))    flag = false ;
            union_set(x, y) ;
            data[count++] = x ;
            data[count++] = y ;
        }
        for(y=1; y<count; y++)
            if(find_set(data[0])!=find_set(data[y]))
                flag = false ;
        if(flag)    printf("Case %d is a tree.\n", t ++) ;
        else    printf("Case %d is not a tree.\n", t ++);
    }
    return 0 ;

 

 

posted on 2012-01-31 00:34  追逐.  阅读(229)  评论(0编辑  收藏  举报