注意几个小细节就好了
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; } }