//目录

并查集,是否成树,Poj(1308)

思路:

对于每一条新的边的两个端点,是否是属于一颗树,要是的话,就不是一颗树。否则,就合并。

这里要注意的是,不能是森林,我这里WA了两次了。只不过在最后,查看每个节点的祖先是否是同一个就可以了。

#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

const int maxn = 105;

int father[maxn];
bool vis[maxn];

int Find_set(int x)
{
    if(x!=father[x])
        father[x]=Find_set(father[x]);
    return father[x];
}

void Union(int x,int y)
{
    father[y] = x;
}

int main()
{
    bool flag;
    int x,y;
    int t=0;
    while(scanf("%d%d",&x,&y),x!=-1)
    {
        flag=true;
        if(x==0&&y==0)
        {
            printf("Case %d is a tree.\n",++t);
            continue;
        }

        else {
            for(int i=0;i<maxn;i++)
            {
                father[i] = i;
                vis[i] = false;
            }

            int first = x;
            vis[x]=vis[y]=true;
            if(Find_set(x)==Find_set(y))
                flag=false;
            else Union(x,y);

            while(scanf("%d%d",&x,&y),x!=0)
            {
                vis[x]=vis[y]=true;
                int fx=Find_set(x);
                int fy=Find_set(y);
                if(fx==fy)
                    flag=false;
                else Union(fx,fy);
            }
            for(int i=0;i<maxn;i++)
            {
                if(vis[i]&&Find_set(first)!=Find_set(i))
                {
                    flag=false;
                    break;
                }
            }
            if(flag)
                printf("Case %d is a tree.\n",++t);
            else printf("Case %d is not a tree.\n",++t);

        }


    }
    return 0;
}

 

posted @ 2016-06-22 23:16  小草的大树梦  阅读(232)  评论(0编辑  收藏  举报