HDU 1325 Is It A Tree?(并查集)

题意:给你一些有向边,问是否能构成一棵树。。

思路:1、把树的边当成是无向边,则所有的点属于同一个集合,使用并查集

2、所有点至多只能有一个入度。

3、根节点只能有一个

4、特判0,0,

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;
const int N = 1009;
int fa[N] ;
bool visit[N];
int finfa(int k)
{
    if(k==fa[k]) return k;
    return fa[k] = finfa(fa[k]);
}
void un(int a,int b)
{
    fa[finfa(a)] = fa[finfa(b)];
}
int in[N],root;
int main()
{
    freopen("in.txt","r",stdin);
    int a,b,T = 1;
    while(scanf("%d%d",&a,&b)&&(a>=0||b>=0))
    {
        bool fig = false;
        if(a==0&&b==0)
        {
            printf("Case %d is a tree.\n",T++);
            continue;
        }
        memset(visit,false,sizeof(visit));
        memset(in,0,sizeof(in));root = 0 ;
        for(int i=0;i<N;i++) fa[i] = i;
        un(a,b);visit[a] = visit[b] = true;
        in[b]++;
        while(~scanf("%d%d",&a,&b)&&(a+b))
        {
            un(a,b);
            visit[a] = visit[b] = true;
            in[b]++;
          //  cout<<in[b]<<"  LLL"<<endl;
        }
        int rt = -1;
        for(int i=0;i<N;i++)
        if(visit[i])
        {
            //cout<<i<<endl;
            if(!in[i]) root++;
            if(in[i]>1) fig = true;
            if(rt==-1) rt = finfa(i);
            else if(rt!=finfa(i)) fig = true;
        }
        if(root!=1||fig)
        {
            printf("Case %d is not a tree.\n",T++);
        }
        else
        {
            printf("Case %d is a tree.\n",T++);
        }
    }
    return 0;
}


你可能感兴趣的:(HDU 1325 Is It A Tree?(并查集))