标签:数据 题意 i++ class cas show bsp 集合 ios
题意:
判断所给的数据能否构成一颗树。
题解:
题目中所给的是有向树,并给出了性质:
1.只有一个节点,称为根节点,没有定向边指向它。
2.除了根节点外,每个节点都只有有一条指向它的边。
3.从树根到任一结点有一条有向通路。
抽象过来就是三个条件:
1.只有一个入度为0的点,作为根节点。
2.除根节点外,其他点的入度只能为1。
3.所有点都能连通,也就是所有点需要在一个集合中,使用并查集来划分集合。
注意!!!可能会出现空树,也就是0 0,空树也是树。
代码:
#include<iostream> #include<stdio.h> #include<math.h> #include<algorithm> #include<vector> #include<cstring> using namespace std; typedef long long ll; const int maxn = 2e5+7; int f[maxn],d[maxn],vis[maxn],in[maxn]; int a,b; int Find(int x) { return f[x]==x?x:f[x]=Find(f[x]); } void join(int x,int y) { int fx=Find(x); int fy=Find(y); if(fx!=fy) { f[fy]=fx; } } int main() { int Case=1; while(~scanf("%d%d",&a,&b)) { if(a==-1 && b==-1)break; for(int i=0; i<maxn; i++)f[i]=i,in[i]=0,vis[i]=0; if(a==0 && b==0) { printf("Case %d is a tree.\n",Case++); continue; } vis[a]=1; vis[b]=1; in[b]++; join(a,b); while(~scanf("%d%d",&a,&b)) { if(a==0 && b==0)break; vis[a]=1; vis[b]=1; in[b]++; join(a,b); } int flag=1; int root=0; int cnt=0; for(int i=1;i<maxn;i++) { if(vis[i] && in[i]==0)root++;///根节点个数 if(in[i]>=2)flag=0;///除了根节点外,其他点入度为1 if(vis[i] && f[i]==i)cnt++;///判断所有点是否都在一个集合 } if(root!=1 || cnt>1)flag=0; if(flag)printf("Case %d is a tree.\n",Case++); else printf("Case %d is not a tree.\n",Case++); } return 0; }
标签:数据 题意 i++ class cas show bsp 集合 ios
原文地址:https://www.cnblogs.com/j666/p/11614365.html