そして-----であることAツリーのツリーセットをチェック!

注:初期チェックの祖先とFを設定する必要があり、[I] = I; !!!!

互いに素セットの決定木:

1.空の木、無ノードツリー

2.ルート・ノードの数を分析し、ツリーが1以下であります

3. Aの親ノードの複数、または既存の関係

4.番号が連続していない、ノードが記録される場合がVIS [N]

#include<cstdio>
#include<cstring>
#include<cstdlib>
#define N 100000
int f[N], flag, vis[N];
int getf(int x)
{
    if (x == f[x])
        return x;
    else
    {
        f[x] = getf(f[x]);
        return f[x];
    }
}
void merge(int a, int b)
{
    int x = getf(a);
    int y = getf(b);
    if (x != y)
        f[b] = a;
}
int main()
{
    int a, b, i;
    int ans = 1;///输入组数
    int cnt = 0;
    memset(vis, 0, sizeof(vis));
    for(i = 1; i <= N; i++)
        f[i] = i;
    flag = 0;
    while(1)
    {
        scanf("%d %d", &a, &b);
        if(a == -1 && b == -1)
            break;
        if (a == 0 && b == 0)
        {
            for(i = 1; i <= N; i++)
            {
                if(f[i] == i && vis[i])
                    cnt++;///树根个数
                if (cnt > 1)
                    break;
            }
            if (flag || cnt > 1)///如果没有环 也不是森林
                printf("Case %d is not a tree.\n", ans++);
            else
                printf("Case %d is a tree.\n", ans++);
            memset(vis, 0, sizeof(vis));
            for(i = 1; i <= N; i++)
                f[i] = i;
            flag = 0;
            cnt = 0;
            continue;
        }
        vis[a] = vis[b] = 1;
        if (f[a] == f[b] || f[b] != b)///合并之前已在同一棵树上 或b结点已经有父亲
            flag = 1;
        merge(a, b);//合并
    }
    return 0;
}


公開された29元の記事 ウォンの賞賛4 ビュー4703

おすすめ

転載: blog.csdn.net/onion___/article/details/79136589