Is It A Tree? HDU

Posted HelloHeBin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Is It A Tree? HDU相关的知识,希望对你有一定的参考价值。

题意:有向图判断是否是树。

树是一种众所周知的数据结构,它要么是空的,要么是一组由足以下条件的节点之间的定向边连接的一个或多个节点。

正好有一个节点,称为根,没有定向边指向该节点。
除了根节点外,每个节点都有一条指向它的边。
从根到每个节点都有一个唯一的有向边序列。

分析:对于一棵非空树,有如下性质

  1. 每个点入度为0或1.
  2. 入读为0的点只有一个,且由该点可以单向遍历到其余全部点.
  3. 点数 n = 边数 m + 1.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10, INF = 0x3f3f3f3f;

int n, m, h[N], idx;
struct T 
    int to, nx;
 g[N];
int in[N], out[N], st[N];

void add(int u, int v) 
    g[idx] = v, h[u], h[u] = idx++;

int dfs(int u)   // 记录该树的所有节点数量
    int res = 1; st[u] = 1;
    for (int i = h[u]; ~i; i = g[i].nx) 
        int v = g[i].to;
        if (!st[v]) res += dfs(v);
    
    return res;

bool flag = 1;
bool is_tree() 
    if (n == 0) return 1;  // 空树
    if (!flag) return 0;  // 入度 > 1
    int rt = 0;
    for (int i = 1; i <= n; i++) 
        if (!in[i] && out[i]) 
            rt = i; break; // 根节点 rt, 记录该树的节点数量
        
    
    if (rt == 0) return 0;
    int k = dfs(rt);
    // printf("k,m: %d %d\\n", k, m);
    return k == m + 1;

int main_ac() 
    int a, b, t = 0;
    memset(h, -1, sizeof(h)), idx = 0, n = 0, m = 0;
    while (~scanf("%d%d", &a, &b), ~a) 
        if (a + b == 0) 
            printf("Case %d is%s a tree.\\n", ++t, is_tree() ? "" : " not");

            memset(h, -1, sizeof(h)), idx = 0, n = 0, m = 0, flag = 1;
            memset(in, 0, sizeof(in));
            memset(out, 0, sizeof(out));
            memset(st, 0, sizeof(st));
            continue;
        
        add(a, b), m++, n = max(n, max(a, b)), in[b]++, out[a]++;
        if (in[b] > 1)
            flag = 0;
    
    return 0;

/********************/
bool is_tree2() 
    // printf("chk: %d %d %d\\n", n, m, flag);
    return n == 0 || n == m + 1 && flag;

int main() 
    int a, b, t = 0;
    while (~scanf("%d%d", &a, &b) && ~a) 
        if (a + b == 0) 
            printf("Case %d is%s a tree.\\n", ++t, is_tree2() ? "" : " not");
            n = 0, m = 0, flag = 1;
            memset(in, 0, sizeof(in));
            memset(out, 0, sizeof(out));
            continue;
        
        m++;
        n += !(out[a] + in[a]), out[a]++;
        n += !(out[b] + in[b]), in[b]++;
        if (in[b] > 1) flag = 0;
    
    return 0;

以上是关于Is It A Tree? HDU的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1325 Is It A Tree?

hdu1325 Is It A Tree? solution

HDU 1325 Is It a Tree?

HDU 1325 Is It A Tree?

HDU 1325,POJ 1308 Is It A Tree

Is It A Tree? HDU