POJ1308

注意几个小细节就好了

1.空树也是树

2.不能有指向自身节点的边

3.节点入度必须有一个为0,其他都为1(避免环的存在)

代码就很简单了,水题,反正俺是个只会水题的垃圾

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 2e5 + 15;
int pre[maxn];
int rudu[maxn];
bool vis[maxn];//Judge节点是否出现过
int find(int u)
{
    if(u!=pre[u])
    {
        pre[u] = find(pre[u]);
    }
    return pre[u];
}
int main()
{
    int kase = 0;
    int u,v;//树节点
    bool flag = true;
    while(cin>>u>>v)
    {
        if(u==-1)
            break;
        if(u+v==0)
        {
            int i,tmp,cnt = 0,ans = 0;//ans用来判断空树
            for(i=1;i!=maxn;++i)
                if(vis[i])
                {//节点被访问过
                    ++ans;
                    tmp = pre[i];
                    if(rudu[i]==0)
                        ++cnt;
                }
            if(cnt!=1)
                flag = false;
            for(;i!=maxn;++i)
                if(vis[i])
                {
                    if(pre[i]!=tmp)
                    {
                        flag = false;
                        break;
                    }
                }
            if(ans==0)
                flag = true;
            if(flag)
                printf("Case %d is a tree.
",++kase);
            else
                printf("Case %d is not a tree.
",++kase);
            flag = true;
            memset(rudu,0,sizeof(rudu));
            memset(vis,false,sizeof(vis));
            for(int v=1;v<=maxn;++v)
                pre[v] = v;
            continue;
        }
        vis[u] = vis[v] = true;// u ~ v节点被访问过了
        if(u==v)
        {
            flag = false;//自己指向自己的边
        }
        if(!flag)
            continue;//剪枝
        ++rudu[v];
        if(rudu[v]>1)
        {
            flag = false;
            continue;
        }
        int f1 = find(u);
        int f2 = find(v);
        if(f1!=f2)
            pre[f1] = f2;
    }
}
不怕万人阻挡,只怕自己投降。
原文地址:https://www.cnblogs.com/newstartCY/p/11604431.html