zoukankan      html  css  js  c++  java
  • 树的判定两道题

    1.判断有向图是否是树

    POJ 1308 --- Is It A Tree ?    

    题目链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=39051#problem/G

    有向图是否为树的判断条件:

    1.树中每个节点至多只能有一个父节点。

    2.树中不能出现环。

    3.树中只能有一个根节点。

    用并查集来解,则条件转化为:

    1'.一个节点要连接到另一个节点的后面,则该节点必须是根节点,否则会出现两个根节点的情况。

    2'.如果两个节点已经属于同一个集合,则不能在合并,否则会出现环。

    3'.最后统计根节点(fa[i] == i)的个数,如果大于一个,则不是树。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 1000100
    
    int fa[N],flag[N];
    
    void makeset(int n)
    {
        for(int i=1;i<=n;i++)
        {
            fa[i] = i;
            flag[i] = 0;
        }
    }
    
    int findset(int x)
    {
        if(x != fa[x])
        {
            fa[x] = findset(fa[x]);
        }
        return fa[x];
    }
    
    int unionset(int a,int b)
    {
        int x = findset(a);
        int y = findset(b);   //b永远是a的子节点
        if(x == y)            //已经是一个集合,再合并会形成环
            return 1;
        if(fa[y] != b)         //b不是根节点
            return 1;
        else
        {
            fa[y] = x;
            return 0;
        }
    }
    
    int main()
    {
        int a,b,i,maxi,gen,bad;
        int cs = 1;
        bad = 0;
        maxi = 0;
        makeset(N-1);
        while(1)
        {
            scanf("%d%d",&a,&b);
            if(a == -1 && b == -1)
                break;
            maxi = max(maxi,max(a,b));
            if(a == 0 && b == 0)
            {
                gen = 0;
                for(i=1;i<=maxi;i++)
                {
                    if(flag[i] == 1 && fa[i] == i)  //是否根节点 
                    {
                        gen++;
                    }
                    if(gen>1)
                        break;
                }
                if(gen>1 || bad>0)
                    printf("Case %d is not a tree.
    ",cs++);
                else
                    printf("Case %d is a tree.
    ",cs++);
                bad = 0;
                maxi = 0;
                makeset(N-1);
            }
            else
            {
                flag[a] = flag[b] = 1;
                bad += unionset(a,b);
            }
        }
        return 0;
    }
    View Code

    作者:whatbeg
    出处1:http://whatbeg.com/
    出处2:http://www.cnblogs.com/whatbeg/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    更多精彩文章抢先看?详见我的独立博客: whatbeg.com

  • 相关阅读:
    二分排序之三行代码
    最短路径—Floyd算法
    最小生成树 Kruskal算法
    最小生成树-Prim算法
    最短路径之迪杰斯特拉(Dijkstra)算法
    C函数指针
    Linux进程的实际用户ID和有效用户ID
    C++ 之Boost 实用工具类及简单使用
    ELK之消息队列选择redis_kafka_rabbitmq
    Python文件操作
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3498213.html
Copyright © 2011-2022 走看看