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

          并查集 (2) - PKU1611 The Suspects

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


          主站蜘蛛池模板: 清镇市| 芒康县| 绵阳市| 手机| 西林县| 南涧| 玉树县| 茂名市| 呈贡县| 鄄城县| 平果县| 南华县| 辉县市| 淳安县| 额尔古纳市| 镇原县| 高密市| 曲周县| 永州市| 宣化县| 青阳县| 永寿县| 定远县| 桦川县| 荥经县| 洞头县| 贵溪市| 石门县| 甘谷县| 精河县| 吉林省| 宣城市| 卢氏县| 旺苍县| 体育| 库尔勒市| 阿克陶县| 色达县| 遂宁市| 招远市| 高密市|