HDU 1325 Is It A Tree?

传送门

这个题是判断是否为树。
树的边是有向的,树也可以为空。
代码里面,s指子结点集,total指结点集,v指边集。
还有一个坑,最后结束标志是负数而不一定-1

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <unordered_set>
using namespace std;

const int MAXN = 1e6;
int a, b;
int c = 1;
int conn = 0;
int pre[MAXN];

struct Edge
{
    int from, to;
};
vector<Edge> v;
unordered_set<int> s;
unordered_set<int> total;

int f(int n)
{
    int f0 = n, f1 = n;
    int t;
    for (; pre[f0] > 0;)
    {
        f0 = pre[f0];
    }
    for (; pre[f1] > 0;)
    {
        t = f1;
        f1 = pre[f1];
        pre[t] = f0;
    }
    return f0;
}

bool u(int n1, int n2)
{
    int f1 = f(n1);
    int f2 = f(n2);
    if (f1 != f2)
    {
        conn++;
        if (pre[f1] <= pre[f2])
        {
            pre[f1] += pre[f2];
            pre[f2] = f1;
        }
        else
        {
            pre[f2] += pre[f1];
            pre[f1] = f2;
        }
        return true;
    }
    return false;
}

void judge()
{
    if (v.size() == 0)
    {
        printf("Case %d is a tree.\n", c);
        return;
    }
    if (v.size() != s.size())
    {
        printf("Case %d is not a tree.\n", c);     // 判定重指
        return;
    }
    for (int i = 0; i < v.size(); i++)
    {
        if (!u(v[i].from, v[i].to))
        {
            printf("Case %d is not a tree.\n", c);  // 判定一切环,包括有环连通图和有环非连通图
            return;
        }
    }
    if (conn + 1 != total.size())   // 此时conn已经等于v.size()
    {
        printf("Case %d is not a tree.\n", c);     // 判定无环非连通图
        return;
    }
    printf("Case %d is a tree.\n", c);
}
                                                                  // 顺便说一句,v.size()+1!=total.size()应付不了有环非连通图
int main()
{
    memset(pre, -1, sizeof pre);
    for (; ~scanf("%d%d", &a, &b);)
    {
        if (a < 0) break;   // 坑!
        if (a == 0)
        {
            judge();
            memset(pre, -1, sizeof pre);
            c++;
            conn = 0;
            v.clear();
            s.clear();
            total.clear();
            continue;
        }
        v.push_back({ a,b });
        s.insert(b);
        total.insert(a);
        total.insert(b);
    }

    return 0;
}
posted @ 2017-04-08 20:19  CrossingOver  阅读(92)  评论(0编辑  收藏  举报