zoukankan      html  css  js  c++  java
  • poj 1308 Is It A Tree?

    题意:给一个有向图,判断是否为有根数树

    这题应该来讲是个水题但是OJ将其归为星题,主要是容易WA,理清逻辑就可以了

    注意:

    有根树的判定,1.连通,2边数+1 = 点数 3.无环    由两个可以推到另一个

    做这题紧紧抓住树的定义即可,另外处理一下下面的一些特殊情况

    1.题意要求是树,不能是森林

    2.空树也是树,题目一开始说了

    3.数据中可能有自环,即1 1这种,这样就不是一棵树了

    3.有重边,1 2 , 1 2,同样不是树

    4.有环,1 2 , 2 1,同样不是树

    5.横叉边  2 3 , 4 3  , 同样不是树

    网上都说并查集,其实不用那么麻烦,就模拟一下即可

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    #define N 10010
    #define M 1010
    #define INF 0x3f3f3f3f
    
    bool istree;
    int Min,Max,node,edge,Count;
    int inde[N];
    int num[N],e[N][M];
    bool used[N],vis[N];
    
    inline int max(int a ,int b)
    {
        return a > b ? a : b;
    }
    inline int min(int a , int b)
    {
        return a < b ? a : b;
    }
    
    void dfs(int u)
    {
        vis[u] = true;
        Count++;
        for(int i=0; i<num[u]; i++)
        {
            int v = e[u][i];
            if(vis[v]) //有环或横叉边
            { istree = false; return ;}
            dfs(v);
            if(!istree) return ;
        }
    }
    
    void solve()
    {
        int cc = 0;
        if(edge + 1 != node) 
        { 
            istree = false; 
            return; 
        }
        istree = true;
        memset(vis,false,sizeof(vis));
        for(int i=Min; i<=Max; i++)
            if(used[i] && inde[i] == 0)
            {
                cc++; //一个连通分量
                dfs(i);
                if(!istree) break;
            }
        if(cc != 1) istree = false; //连通分量数不为1
    
    }
    
    int main()
    {
        int cas = 0;
        int u,v;
        while(cin >> u >> v)
        {
            if(u == -1 && v == -1) break;
            if(u == 0 && v == 0) //空树
            {
                printf("Case %d is a tree.\n",++cas);
                continue;
            }
    
            memset(inde,0,sizeof(inde));
            memset(num,0,sizeof(num));
            memset(used,false,sizeof(used));
            Min = min(u,v);
            Max = max(u,v);
            node = 2; edge = 1;
            used[u] = used[v] = true;
            e[u][num[u]++] = v;
            inde[v]++;
            while(cin >> u >> v)
            {
                if(u == 0 && v == 0) break;
                inde[v]++; edge++;
                e[u][num[u]++] = v;
                Min = min(Min,u); Min = min(Min,v);
                Max = max(Max,u); Max = max(Max,v);
                if(!used[u]) node++ , used[u] = true;
                if(!used[v]) node++ , used[v] = true;
            }
            solve();
            if(istree)    printf("Case %d is a tree.\n",++cas);
            else        printf("Case %d is not a tree.\n",++cas);
        }
        return 0;
    }
  • 相关阅读:
    唯一的确定一棵二叉树
    Educational Codeforces Round 55 (Rated for Div. 2)
    524 (Div. 2) Masha and two friends
    单链表实现n(n≥20)的阶乘
    表达式的后缀表示
    UPCOJ2012 The King’s Walk(dp)
    第七届山东省省赛D Swiss-system tournament(归并排序)
    第七届山东省省赛C Proxy(最短路)
    hihocoder1185 连通性·三
    hihocoder1184 连通性二·边的双连通分量
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3123863.html
Copyright © 2011-2022 走看看