题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1325
题目大意:给你n对数a、b。表示a是b的父亲节点,遇到a==0 && b==0 时结束。然后根据当前信息,判断是否能构成一棵树。
思路:然后注意三点就行了。
1.树只有一个根节点。
2.不能构成一个环状
3.父亲节点可以指向多个孩子节点,但是一个孩子节点不能被多个父亲节点所指
然后,弄一个flag=0,违反一点就置为1,就行了,唉

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 100070;
int a;
int father[maxn];
int judge[maxn]={0};            //表示一个节点被指的次数,如果一旦被指次数大于等于2,说明不是树 
int flag;
void make_set(int x)
{
    for(int i=1;i<=x;++i)
    {
        father[i]=i;    
    }
} 
int find_father(int x)
{
    if(x!=father[x])
    {
        father[x]=find_father(father[x]);
    }
    return father[x];
}
void join(int x,int y)
{
    int p,q;
    p=find_father(x);
    q=find_father(y);
    if(p!=q)
    {
        father[q]=p;
    }
    judge[y]++;                        //y被指的次数加一 
    if(judge[y]==2)                    //一旦大于等于2,表明这不可能是树了 
    {
        flag=1;
    }    
}
int main()
{
    int a,b;
    flag=0;
    make_set(maxn-1);
    int e=0;
    while(scanf("%d %d",&a,&b),!(a<0 && b<0))            //循环读入父亲节点和孩子节点 
    {
        if(a==0 && b==0)                                //读入结束,这个时候开始判断是否只有一个根节点 
        {
            int temp;                                
            int flag2=1;                                //树立2号旗帜 
            for(int i=1;i<=maxn-1;i++)                    //遍历所有的结点 
            {
                if( i!=father[i] && flag2==1)            //如果i!=father[i]表示找到一个根节点,第一次走这里 
                {
                    temp=father[i];                        //用temp把根节点存起来 
                    flag2=0;
                }else if(i!=father[i] && flag2==0 && temp!=father[i])    //第二次之后走这里呗,如果遇到第二个树的根节点,代表又不是树了 
                {
                        flag=1;
                }
            }
            e++;
            if(flag==1)    printf("Case %d is not a tree.\n",e);    //如果flag被置为1,说明至少有一个条件不符合 
            else    printf("Case %d is a tree.\n",e);
            make_set(maxn-1);                                    //重新初始化一下 
            for(int i=0;i<maxn;i++)
            {
                judge[i]=0;
            }
            flag=0;
            continue;
        }
        int m=find_father(a);            //找a的父亲结点 
        int n=find_father(b);            //找b的父亲节点 
        if(m==n) flag=1;                //如果a和b的节点相同,说明构成环了,flag置为1 
        join(a,b);                        //把a和b联合起来 
    }
    return 0;
}
Last modification:September 19th, 2019 at 12:30 am
如果觉得我的文章对你有用,请随意赞赏