posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          并查集 (2) - PKU1611 The Suspects

          Posted on 2007-07-15 11:12 ZelluX 閱讀(478) 評論(0)  編輯  收藏 所屬分類: Algorithm
          突然想通了一開始一直超時的原因。
          每次我都是把新的suspect并入第一個元素所在的集合中,但是由于使用了優(yōu)化后的并集操作,有可能是第一個元素所在的集合并入了新的suspect所在的集合,也就是說此后last變量并沒有指向第一個元素所在集合的跟結(jié)點。于是在Union方法中,parent[root1]可能得到一個正整數(shù),并導(dǎo)致Find方法死循環(huán)(根結(jié)點的parent為正)

          后來把Find方法放到Union方法中,問題解決了。

          #include <iostream>

          using namespace std;

          const int DEFAULT_SIZE = 100;

          class UFSets
          {
          private:
              
          int *parent;
              
          int size;
          public:
              UFSets(
          int s = DEFAULT_SIZE);
              
          ~UFSets() { delete [] parent; }
              
          void Union(int root1, int root2);
              
          int Find(int x);
              
          void Clear(int n);
          };

          UFSets::UFSets(
          int s)
          {
              size 
          = s;
              parent 
          = new int[size + 1];
              
          for (int i = 0; i <= size; i++)
                  parent[i] 
          = -1;
          }

          int UFSets::Find(int x)
          {
              
          int result = x;
              
          while (parent[result] >= 0)
                  result 
          = parent[result];
              
          return result;
          }

          void UFSets::Union(int root1, int root2)
          {
              
          // The old version didn't contain the following 3 setences.
              root1 = Find(root1);
              root2 
          = Find(root2);
              
          if (root1 == root2) return;

              
          int temp = parent[root1] + parent[root2];
              
          if (parent[root2] < parent[root1])
              {
                  parent[root1] 
          = root2;
                  parent[root2] 
          = temp;
              }
              
          else
              {
                  parent[root2] 
          = root1;
                  parent[root1] 
          = temp;
              }
          }

          void UFSets::Clear(int n)
          {
              
          for (int i = 0; i < n; i++)
                  parent[i] 
          = -1;
          }

          int main()
          {
              UFSets sets(
          30000);
              
          int n, m;
              
          while (true)
              {
                  cin 
          >> n >> m;
                  
          if (n == 0break;
                  sets.Clear(n);
                  
          for (int i = 0; i < m; i++)
                  {
                      
          int t;
                      cin 
          >> t;
                      
          int last, x;
                      cin 
          >> last;
                      last 
          = sets.Find(last);
                      
          for (int j = 1; j < t; j++)
                      {
                          cin 
          >> x;
                          sets.Union(last, x);
                          
          // int temp = sets.Find(x);
                          
          // if (temp != last)
                          
          //     sets.Union(last, temp);
                      }
                  }
                  
          int result = 1;
                  
          int target = sets.Find(0);
                  
          for (int i = 1; i < n; i++)
                      
          if (sets.Find(i) == target)
                          result 
          ++;
                  cout 
          << result << endl;
              }
              
          return 0;
          }


          主站蜘蛛池模板: 安义县| 汤原县| 普安县| 曲靖市| 将乐县| 济源市| 改则县| 贵德县| 海南省| 武陟县| 启东市| 顺平县| 柳州市| 定襄县| 民县| 长泰县| 古浪县| 阜新市| 南雄市| 花莲县| 常熟市| 巴塘县| 文化| 福清市| 周至县| 卓尼县| 阿拉善盟| 措美县| 黔东| 台南市| 泰兴市| 合肥市| 敖汉旗| 嵊泗县| 通山县| 漳浦县| 依安县| 涿州市| 乐东| 驻马店市| 启东市|