您的位置:首页 > 其它

Is It A Tree?(并查集)

2018-01-25 17:28 260 查看

题目:

  给出一对对的数字a,b,表示从a到b有一条边。判断这是不是一棵树。

多case,每个case以0 0 结尾
输入以-1 -1结尾
分析:①每个节点(除了根结点)只有一个入度;②只有一个根结点。

森林:多个根。

入度:指向同一个结点的边数。

将点逐个加入集合中,然后判断就行了。

#include<stdio.h>

#include<algorithm>

using namespace std;

int flagt;//判断是否成树

int vis[10005];//标记用过的结点

int pre[10005];

int find(int x)//压缩路径 并查找

{

    return pre[x]==x?x:pre[x]=find(pre[x]);

}

void Merge(int x,int y)

{

    int fx=find(x);

    int fy=find(y);

    if(fy!=fx)

        pre[fy]=fx;

}

void init()

{

    int i;

    for(i=1;i<=10005;i++)

    {

        pre[i]=i;

        vis[i]=0;

    }

}

int judge_tree(int n) //判断是否只有一个根结点。

{

    int i=1;

    while(i<=n && !vis[i])

        i++;

    int f1=find(i);

    while(i<=n)

    {

        if(vis[i] && find(i)!=f1)

            return 0;

        i++;

    }

    return 1;

}

int main()

{

    int i,j,k=1;

    int x,y,range;

    flagt=1;

    range=0;

    init();

    while(scanf("%d%d",&x,&y)!=EOF)

    {

        if(x<0 || y<0)

            return 0;

        if(x==0 || y==0) //输入0 0时判断。

        {

            if(flagt && judge_tree(range))

                printf("Case %d is a tree.\n",k++);

            else

                printf("Case %d is not a tree.\n",k++);

            flagt=1;

            range=0;

            init();

            continue;

        }

        if(!flagt)

            continue;

       range=max(range,max(x,y));//所涉及到的最数值最大的点。

        vis[x]=vis[y]=1;

        

        if(find(x)==find(y))//他们有共同的根结点,并且他们之间还有父子关系(即有边相连),则无法形成树。

            flagt=0;

        Merge(x,y);

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: