一道数据结构题 想了很久 并查集?

maview 2013-07-03 09:13:56
Description
有n个独立的磁铁(1,2,⋯n标号)放在桌上,一个人对这n堆进行移动操作,然后另一个人询问。

有以下规则:

M X Y : 将含有编号X的磁铁块放在包含Y的磁铁块的顶端。(磁铁块指很多磁铁吸在了一起)

C X : 询问在编号X磁铁下的磁铁的数目。

Input Format
第1行一个整数,操作数p。

第2行到第p+1行:每一行是个合法操作,形如M X Y或C X。

Output Format
对于每个C操作输出一行,即对应的磁铁数。

Sample Input
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4

Sample Output
1
0
2

About Test Data
对于全部数据:1≤n≤30000;1≤p≤100000
对于50%的数据: 1≤n≤1000;1≤p≤10000


就是这样一道题目,请问该怎么做呢?并查集?

十分感谢大家!
...全文
194 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
橡木疙瘩 2013-07-03
  • 打赏
  • 举报
回复
引用 3 楼 FancyMouse 的回复:
并查集无误。合并的时候多做几步操作就是。 1L 2L的办法总复杂度都会退化到平方的。数据很好构造。
什么情况下会退化到平方?能举个例子吗? 空间效率确实不高。
FancyMouse 2013-07-03
  • 打赏
  • 举报
回复
并查集无误。合并的时候多做几步操作就是。 1L 2L的办法总复杂度都会退化到平方的。数据很好构造。
橡木疙瘩 2013-07-03
  • 打赏
  • 举报
回复
方法二: 磁铁信息使用链接信息,同组磁铁组成链表,需要能够通过任一元素找到链表首尾,可以使用双向链,或者使用带头标志的循环链。下面用双向链为例: 初始化:所有磁铁prev=null,next=null M命令: 找到Y所在链表首HY,O(N) 找到X所在链表尾TX,O(N) 连接两个链表,O(N) C命令: 找到从X遍历到链表尾并计数,O(N) 可以在磁铁信息中保存“其下磁铁数”的信息以加快C命令: 在M命令的第一步时,可以计算出Y链表的长度(Y中的位置信息+遍历过的节点数) 在M命令的第二步时,先找到X所在链表首,再遍历到链表尾,所有节点的位置信息+Y链表长度
橡木疙瘩 2013-07-03
  • 打赏
  • 举报
回复
方法一:数据分为两部分,磁铁数组和磁铁组表。 磁铁数组包含所有磁铁信息,磁铁信息中有磁铁组号(或指针)、该铁在组中的位置(就是其下有多少磁铁。 磁铁组是个线性表,元素是磁铁号,只要求遍历、添加、合并功能,用链表实现。 初始化:所有磁铁,位置为0;为所有磁铁创建单元磁铁组表。 M命令:找到X所在磁铁组GX、,O(1)操作; 找到Y所在磁铁组GY,O(1)操作; 遍历GX中的元素,将对应磁铁信息中的磁铁组号(或指针)改为GY,位置加上Length(GY),O(N)操作 GY合并到GX中,O(1)操作。 C命令:输出X中的位置信息 初始化时可以不创建磁铁组表,这样就要在M命令中进行判断,分别对GX和GY为空时进行处理
maview 2013-07-03
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
仅供参考
#include <algorithm>
#include <iostream>
#include <functional>
#include <cstring>
using namespace std;
int main() {
    char *Alphabet = "abcdefghijklmnopqrstuvwxyz" ;
    char *Vowels   = "aeiou" ;
    char *AlphaNum = "0123456789abcdef" ;
    char result[45] ;
    char *last ;

    int lenA  = strlen(Alphabet) ;
    int lenV  = strlen(Vowels  ) ;
    int lenAN = strlen(AlphaNum) ;

    cout << "Alphabet = " << Alphabet << endl ;
    cout << "Vowels   = " << Vowels   << endl ;
    cout << "AlphaNum = " << AlphaNum << endl ;

    cout << "\nusing non-predicate versions" << endl ;

    //non-predicate set_difference
    last = set_difference(Alphabet, Alphabet+lenA,
                          AlphaNum, AlphaNum+lenAN,
                          result) ;
    *last = 0 ;
    cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;

    //non-predicate set_intersection
    last = set_intersection(Alphabet, Alphabet+lenA,
                            AlphaNum, AlphaNum+lenAN,
                            result) ;
    *last = 0 ;
    cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;

    //non-predicate set_symmetric_difference
    last = set_symmetric_difference(Alphabet, Alphabet+lenA,
                                    Vowels  , Vowels  +lenV,
                                    result) ;
    *last = 0 ;
    cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;

    //non-predicate set_union
    last = set_union(Alphabet, Alphabet+lenA,
                     AlphaNum, AlphaNum+lenAN,
                     result) ;
    *last = 0 ;
    cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;

    cout << "\nusing predicate versions" << endl ;

    //predicate set_difference
    last = set_difference(Alphabet, Alphabet+lenA,
                          AlphaNum, AlphaNum+lenAN,
                          result  , less<char>()) ;
    *last = 0 ;
    cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;

    //predicate set_intersection
    last = set_intersection(Alphabet, Alphabet+lenA,
                            AlphaNum, AlphaNum+lenAN,
                            result  , less<char>()) ;
    *last = 0 ;
    cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;

    //predicate set_symmetric_difference
    last = set_symmetric_difference(Alphabet, Alphabet+lenA,
                                    Vowels  , Vowels  +lenV,
                                    result  , less<char>()) ;
    *last = 0 ;
    cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;

    //predicate set_union
    last = set_union(Alphabet, Alphabet+lenA,
                     AlphaNum, AlphaNum+lenAN,
                     result  , less<char>()) ;
    *last = 0 ;
    cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;

    return 0 ;
}
我去研究一下!
赵4老师 2013-07-03
  • 打赏
  • 举报
回复
仅供参考
#include <algorithm>
#include <iostream>
#include <functional>
#include <cstring>
using namespace std;
int main() {
    char *Alphabet = "abcdefghijklmnopqrstuvwxyz" ;
    char *Vowels   = "aeiou" ;
    char *AlphaNum = "0123456789abcdef" ;
    char result[45] ;
    char *last ;

    int lenA  = strlen(Alphabet) ;
    int lenV  = strlen(Vowels  ) ;
    int lenAN = strlen(AlphaNum) ;

    cout << "Alphabet = " << Alphabet << endl ;
    cout << "Vowels   = " << Vowels   << endl ;
    cout << "AlphaNum = " << AlphaNum << endl ;

    cout << "\nusing non-predicate versions" << endl ;

    //non-predicate set_difference
    last = set_difference(Alphabet, Alphabet+lenA,
                          AlphaNum, AlphaNum+lenAN,
                          result) ;
    *last = 0 ;
    cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;

    //non-predicate set_intersection
    last = set_intersection(Alphabet, Alphabet+lenA,
                            AlphaNum, AlphaNum+lenAN,
                            result) ;
    *last = 0 ;
    cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;

    //non-predicate set_symmetric_difference
    last = set_symmetric_difference(Alphabet, Alphabet+lenA,
                                    Vowels  , Vowels  +lenV,
                                    result) ;
    *last = 0 ;
    cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;

    //non-predicate set_union
    last = set_union(Alphabet, Alphabet+lenA,
                     AlphaNum, AlphaNum+lenAN,
                     result) ;
    *last = 0 ;
    cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;

    cout << "\nusing predicate versions" << endl ;

    //predicate set_difference
    last = set_difference(Alphabet, Alphabet+lenA,
                          AlphaNum, AlphaNum+lenAN,
                          result  , less<char>()) ;
    *last = 0 ;
    cout << "set_difference(Alphabet, AlphaNum) =  " << result << endl ;

    //predicate set_intersection
    last = set_intersection(Alphabet, Alphabet+lenA,
                            AlphaNum, AlphaNum+lenAN,
                            result  , less<char>()) ;
    *last = 0 ;
    cout << "set_intersection(Alphabet, AlphaNum) =  " << result << endl ;

    //predicate set_symmetric_difference
    last = set_symmetric_difference(Alphabet, Alphabet+lenA,
                                    Vowels  , Vowels  +lenV,
                                    result  , less<char>()) ;
    *last = 0 ;
    cout << "set_symmetric_difference(Alphabet, Vowels) =  " << result << endl ;

    //predicate set_union
    last = set_union(Alphabet, Alphabet+lenA,
                     AlphaNum, AlphaNum+lenAN,
                     result  , less<char>()) ;
    *last = 0 ;
    cout << "set_union(Alphabet, AlphaNum) =  " << result << endl ;

    return 0 ;
}
maview 2013-07-03
  • 打赏
  • 举报
回复
引用 3 楼 FancyMouse 的回复:
并查集无误。合并的时候多做几步操作就是。 1L 2L的办法总复杂度都会退化到平方的。数据很好构造。
还请问c++stl中有并查集的库么?

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧