并查集,是否成树,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;
}
时间: 2024-10-11 01:28:37

并查集,是否成树,Poj(1308)的相关文章

并查集水题 POJ 1611

题意:有n(n<=30000)个学生,每个学生属于一个团体(可以属于多个团体),共有m(<=500)个团体,如果一个学生是嫌疑人,则他所在的团体的所有人都是嫌疑人,初始时0号学生是嫌疑人.问总共有多少个嫌疑人. 很明显同一个团体的学生可以连一条边,即求0号点所在的连通块有多少个点,用并查集可以很方便的办到,如果两个点属于同一个连通块则把他们的代表元连接起来即可,始终把较小的那个节点作为父节点,所以最后p[0]的节点数就是答案. 代码:

HDU 1325 POJ 1308 Is It A Tree? (并查集)

这道题就是裸并查集,关键在于对不是树几种的判断 1. 空树是树 2. 森林不是树 3. 无环 或者从入度来看:1,无环:2,除了根,所有的入度为1,根入度为0:3,这个结构只有一个根,不然是森林了. 这道题本来暑假做的POJ 1308 但是HDU没有过.在于空树没有考虑. 用并查集判断有多少个森林注意编号是随机的,不是次序.... /* input: 0 0 1 1 0 0 1 2 1 2 0 0 1 2 2 3 4 5 0 0 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9

POJ 1308 Is It A Tree? &amp;&amp; NYOJ 129 (树的判定+并查集)

[题目链接]click here~~ [题目大意]给定多对节点,判断所有节点能否组成一棵树 [解题思路]并查集的基本操作,定义node,edge,统计node和edge的数目,如果(edge==node-1||node==0)则可以成树 树的判定:n个节点,最多n-1条环,只有一个入度为边,不成0 的点,其他入度不大于1,不过要注意poj数据里如果1 1 0 0也会不符合要求,也就是不能自己指向自己 代码: /* Author:HRW 树的判定: n个节点,最多n-1条边 不成环 只有一个入度为

(并查集)POJ 1308 &amp; HDU 1325

一开始以为两道题是一样的,POJ的过了直接用相同代码把HDU的交了,结果就悲剧了.最后发现HDU的没有考虑入度不能大于一. 题意:用树的定义来 判断吧,无环,n个结点最多有n-1条边,不然就会有环.只有一个入度为0的结点,不存在入度大于1的结点. 思路:并查集. AC代码: #include<stdio.h> #include<string.h> #define N 100005 int in[N],pre[N],a,b,c[N]; void init()//初始化 { for(i

POJ 1308 Is It A Tree? (并查集)

Is It A Tree? Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23006   Accepted: 7898 Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edge

[POJ 1308]Is It A Tree?(并查集判断图是否为一棵有根树)

Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties. There is exactly one node, called the root, t

POJ - 1308 Is It A Tree?【并查集】

A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties. There is exactly one node, called the root, to which no d

POJ 2524 Ubiquitous Religions (幷查集)

Ubiquitous Religions Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 23090   Accepted: 11378 Description There are so many different religions in the world today that it is difficult to keep track of them all. You are interested in findi

poj 2492 a bug&#39;s life 简单种类并查集

题意大致为找同性恋的虫子.... 这个比食物链要简单些.思路完全一致,利用取余操作实现关系之间的递推. 个人感觉利用向量,模和投影可能可以实现具有更加复杂关系的并查集. 1 #include<cstdio> 2 using namespace std; 3 const int MAXN=50010; 4 int fa[MAXN]; 5 int rel[MAXN]; // 0代表同类,1代表吃fa[i],2代表被吃 6 void _set(int n) 7 { 8 for(int i=1;i&l