pku 1235 Galactic Breakup 并查集

pku 1235 Galactic Breakup 并查集

题意:
一个帝国有N个国家组成,每个国家包括N i个区域(一个小方格),然后第i个国家在第i月会分离出去。问有多少个月帝国仍然是一个整体。
PS:说道帝国,就想到黄金雄教授在ICPC开幕式上用闽南语讲的(。。。ACM大帝国。。),那发音,拿语言的组织都超级搞笑
pku 1235 Galactic Breakup 并查集_第1张图片

思路:
并查集,逆向思维。最后所有的国家应该都是独立的。相当于一个国家一个国家逐月的联合起来。用并查集统计是否当前集合为一个整体即可。暴力的方法没实验过,不过复杂度会高达30^6,(*^__^*) 嘻嘻……,RP好的可以去拼一下~

代码:
 1  // ============================================================================
 2  //  Name        : pku1235.cpp
 3  //  Author      : yzhw
 4  //  Version     :
 5  //  Copyright   : yzhw
 6  //  Description : Hello World in C++, Ansi-style
 7  // ============================================================================
 8 
 9  #include  < iostream >
10  #include  < cstdio >
11  #include  < vector >
12  #include  < algorithm >
13  using   namespace  std;
14  # define LEFT (data[i][j] % (n * m))
15  int   set [ 30000 ],n,m,k,l,data[ 30000 ][ 21 ];
16  bool  used[ 30000 ];
17  int  find( int  pos)
18  {
19       if ( set [pos] == pos)  return  pos;
20       else   return   set [pos] = find( set [pos]);
21  }
22  int  main() {
23       int  testcase;
24      scanf( " %d " , & testcase);
25       while (testcase -- )
26      {
27          scanf( " %d%d%d%d " , & n, & m, & k, & l);
28           int  total = 0 ,ans = 0 ,c;
29           for ( int  i = 0 ;i < n * m * k;i ++ )
30               set [i] = i,used[i] = false ;
31           for ( int  i = 0 ;i < l;i ++ )
32          {
33              scanf( " %d " , & data[i][ 0 ]);
34               for ( int  j = 1 ;j <= data[i][ 0 ];j ++ )
35                  scanf( " %d " , & data[i][j]);
36          }
37           for ( int  i = l - 1 ;i >= 0 ;i -- )
38          {
39              c = 0 ;
40               for ( int  j = 1 ;j <= data[i][ 0 ];j ++ )
41              {
42                  vector < int >  refer;
43                   if (data[i][j] - n * m >= 0 && used[data[i][j] - n * m]) refer.push_back(find(data[i][j] - n * m));
44                   if (data[i][j] + n * m < n * m * k && used[data[i][j] + n * m]) refer.push_back(find(data[i][j] + n * m));
45                   if (LEFT % n != 0 && used[data[i][j] - 1 ]) refer.push_back(find(data[i][j] - 1 ));
46                   if (LEFT % n != n - 1 && used[data[i][j] + 1 ]) refer.push_back(find(data[i][j] + 1 ));
47                   if (LEFT / n != 0 && used[data[i][j] - n]) refer.push_back(find(data[i][j] - n));
48                   if (LEFT / n != m - 1 && used[data[i][j] + n]) refer.push_back(find(data[i][j] + n));
49                  sort(refer.begin(),refer.end());
50                  vector < int > ::iterator end = unique(refer.begin(),refer.end());
51                  c += end - refer.begin();
52                   for ( int  t = 0 ;t < end - refer.begin();t ++ )
53                       set [find(refer[t])] = find(data[i][j]);
54                  used[data[i][j]] = true ;
55              }
56              total = total + data[i][ 0 ] - c;
57               if (total == 1 ) ans ++ ;
58          }
59          printf( " %d\n " ,l - ans);
60      }
61       return   0 ;
62  }

你可能感兴趣的:(pku 1235 Galactic Breakup 并查集)