[2016-03-17][POJ][1308][Is It A Tree]

  • 时间:2016-03-17 15:01:10 星期四

  • 题目编号:[2016-03-17][POJ][1308][Is It A Tree]

  • 题目大意:给定若干条边,问这些边是否组成树

  • 分析:并查集合并边,如果遇到不能合并(祖宗节点一样),就不是树

  • 方法:

    • 注意空树的情况
    • 给出的边号不一定按1~n的顺序,需要vis 做标记,不过这题数据比较水,maxn== 1000,就A了,刚开始vis数组忘记初始化
  1. #include <cstdio>
  2. #include<cstring>
  3. using namespace std;
  4. typedef long long LL;
  5. #define CLR(x,y) memset((x),(y),sizeof((x)))
  6. #define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))
  7. const int maxn = 1000;
  8. int fa[maxn],mrank[maxn],vis[maxn];
  9. void ini(int n){
  10. CLR(mrank,0);
  11. CLR(vis,0);
  12. FOR(i,0,n + 1){
  13. fa[i] = i;
  14. }
  15. }
  16. int fnd(int x){
  17. return x == fa[x]?x:fa[x] = fnd(fa[x]);
  18. }
  19. int uni(int x,int y){
  20. x = fnd(x);
  21. y = fnd(y);
  22. if(x == y) return 0;
  23. if(mrank[x] > mrank[y]){
  24. fa[y] = fa[x];
  25. }else {
  26. fa[x] = fa[y];
  27. if(mrank[x] == mrank[y]) ++mrank[y];
  28. }
  29. return 1;
  30. }
  31. int main(){
  32. //freopen("in.txt","r",stdin);
  33. //freopen("out.txt","w",stdout);
  34. int u,v,flg,cntcase = 0;
  35. while(~scanf("%d%d",&u,&v) && ~u && ~v){
  36. //空树
  37. if(!(u + v)){
  38. printf("Case %d is a tree.\n",++cntcase);
  39. continue;
  40. }
  41. ini(maxn - 1);
  42. flg = 1;
  43. if(flg){
  44. if(uni(u,v)){
  45. vis[v] = vis[u] = 1;
  46. }
  47. else flg = 0;
  48. }
  49. while(~scanf("%d%d",&u,&v) && u && v){
  50. if(flg){
  51. if(uni(u,v)){
  52. vis[v] = vis[u] = 1;
  53. }
  54. else flg = 0;
  55. }
  56. }
  57. //判断不是森林
  58. int cnt = 0;
  59. if(flg){
  60. FOR(i,0,maxn){
  61. if(vis[i] && fa[i] == i){
  62. ++cnt;
  63. }
  64. if(cnt > 1){
  65. flg = 0;break;
  66. }
  67. }
  68. }
  69. if(flg) printf("Case %d is a tree.\n",++cntcase);
  70. else printf("Case %d is not a tree.\n",++cntcase);
  71. }
  72. return 0;
  73. }


来自为知笔记(Wiz)


posted on 2016-03-17 17:08  红洋  阅读(123)  评论(0)    收藏  举报

导航