码迷,mamicode.com
首页 > 其他好文 > 详细

Is It A Tree?——简单并查集应用

时间:2019-09-30 23:47:37      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:数据   题意   i++   class   cas   show   bsp   集合   ios   

题目链接

题意:

判断所给的数据能否构成一颗树。

题解:

题目中所给的是有向树,并给出了性质:
1.只有一个节点,称为根节点,没有定向边指向它。
2.除了根节点外,每个节点都只有有一条指向它的边。
3.从树根到任一结点有一条有向通路。
抽象过来就是三个条件:
1.只有一个入度为0的点,作为根节点。
2.除根节点外,其他点的入度只能为1。
3.所有点都能连通,也就是所有点需要在一个集合中,使用并查集来划分集合。

注意!!!可能会出现空树,也就是0 0,空树也是树。

代码:

技术图片
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 2e5+7;
int f[maxn],d[maxn],vis[maxn],in[maxn];
int a,b;
int Find(int x)
{
    return f[x]==x?x:f[x]=Find(f[x]);
}
void join(int x,int y)
{
    int fx=Find(x);
    int fy=Find(y);
    if(fx!=fy)
    {
        f[fy]=fx;
    }
}
int main()
{

    int Case=1;
    while(~scanf("%d%d",&a,&b))
    {
        if(a==-1 && b==-1)break;
        for(int i=0; i<maxn; i++)f[i]=i,in[i]=0,vis[i]=0;
        if(a==0 && b==0)
        {
            printf("Case %d is a tree.\n",Case++);
            continue;
        }
        vis[a]=1;
        vis[b]=1;
        in[b]++;
        join(a,b);
        while(~scanf("%d%d",&a,&b))
        {
            if(a==0 && b==0)break;
            vis[a]=1;
            vis[b]=1;
            in[b]++;
            join(a,b);

        }
        int flag=1;
        int root=0;
        int cnt=0;
        for(int i=1;i<maxn;i++)
        {
            if(vis[i] && in[i]==0)root++;///根节点个数 
            if(in[i]>=2)flag=0;///除了根节点外,其他点入度为1 
            if(vis[i] && f[i]==i)cnt++;///判断所有点是否都在一个集合 
        }
        if(root!=1 || cnt>1)flag=0;

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

    }

    return 0;
}
View Code

 

Is It A Tree?——简单并查集应用

标签:数据   题意   i++   class   cas   show   bsp   集合   ios   

原文地址:https://www.cnblogs.com/j666/p/11614365.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!