[2016-03-17][HDU][1272][小希的迷宫]

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

  • 题目编号:[2016-03-17][HDU][1272][小希的迷宫]

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

  • 分析:

    • 只有一条通路—>树
  • 方法:

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


来自为知笔记(Wiz)


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

导航