1003 瑞神要考研(模拟,并查集)
1003: 瑞神要考研
时间限制: 1 Sec 内存限制: 128 MB提交: 288 解决: 87
[提交][状态][讨论版]
题目描述
瑞神要准备考研了,为了复习数据结构,瑞神在某宝上买了一本数据结构得考研辅导资料《考研数据结构---从入门到放弃》,从此瑞神开始了愉快的复(zhuang)习(bi)。
有一天,瑞神找了好多条链表来辅助自己复习,但是他在复习的过程中一不小心把链表掉在了地上,捡起来的时候链表以及断成了好多个结点,每个结点只保留了当前结点的地址、结点的值和下一个结点的地址。
瑞神看着这些结点浑身难受无法复习,为了让瑞神继续复(zhuang)习(bi)下去,请你帮瑞神把链表复原。
有一天,瑞神找了好多条链表来辅助自己复习,但是他在复习的过程中一不小心把链表掉在了地上,捡起来的时候链表以及断成了好多个结点,每个结点只保留了当前结点的地址、结点的值和下一个结点的地址。
瑞神看着这些结点浑身难受无法复习,为了让瑞神继续复(zhuang)习(bi)下去,请你帮瑞神把链表复原。
输入
第一行给出结点的个数 n(1<=n<=100000)。
接下来 n 行每行给出一个结点的信息:结点地址、值和下一个结点的地址。
地址为 5 位数字,-1 表示地址为 NULL。
保证每一条链表的最后一个结点的下一个结点地址为-1。
接下来 n 行每行给出一个结点的信息:结点地址、值和下一个结点的地址。
地址为 5 位数字,-1 表示地址为 NULL。
保证每一条链表的最后一个结点的下一个结点地址为-1。
输出
每一行输出一条链表,只输出每个节点的值。
多条链表按照首结点地址从小到大排序。
多条链表按照首结点地址从小到大排序。
样例输入
3
00323 155 -1
00322 87 00323
00233 1 -1
样例输出
1
87 155
提示
模拟链表,
用并查集找头节点,
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN = 1e6 + 5; 5 6 struct Node { 7 //int pre; 8 int val; 9 int nxt; 10 } node[MAXN]; 11 12 int fa[MAXN]; 13 14 int setFind(int x) 15 { 16 if (fa[x] < 0) { 17 return x; 18 } 19 return fa[x] = setFind(fa[x]); 20 } 21 22 void setJoin(int x, int y) 23 { 24 x = setFind(x); 25 y = setFind(y); 26 if (x != y) { 27 fa[y] = x; 28 } 29 } 30 31 int main() 32 { 33 int n; 34 int i; 35 int a, b, c; 36 set<int> st; 37 set<int>::iterator it; 38 int cur; 39 40 while (~scanf("%d", &n)) { 41 memset(fa, -1, sizeof(fa)); 42 st.clear(); 43 for (i = 0; i < n; ++i) { 44 scanf("%d%d%d", &a, &b, &c); 45 node[a].val = b; 46 node[a].nxt = c; 47 if (c != -1) { 48 setJoin(a, c); 49 } 50 st.insert(a); 51 } 52 for (it = st.begin(); it != st.end(); ++it) { 53 //printf("%d, ", *it); 54 if (fa[*it] < 0) { 55 cur = *it; 56 while (node[cur].nxt != -1) { 57 printf("%d ", node[cur].val); 58 cur = node[cur].nxt; 59 } 60 printf("%d\n", node[cur].val); 61 } 62 } 63 } 64 65 return 0; 66 }