### Codeforces 1131 F. Asya And Kittens-雙向鏈表(模擬或者STL list)+並查集(或者STL list的splice()函數)-對不起，我太菜了。。。 (Codeforces Round #541 (Div. 2))

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Asya loves animals very much. Recently, she purchased

Observing the kittens, Asya noticed, that they are very friendly and often a pair of kittens in neighboring cells wants to play together. So Asya started to remove partitions between neighboring cells. In particular, on the day

• Noticed, that the kittens
• Removed the partition between these two cells, efficiently creating a single cell, having all kittens from two original cells.

Since Asya has never putted partitions back, after

For every day, Asya remembers numbers of kittens

Input

The first line contains a single integer

Each of the following

It's guaranteed, that the kittens

Output

For every cell from

All printed integers must be distinct.

It's guaranteed, that there is at least one answer possible. In case there are multiple possible answers, print any of them.

Example
input
Copy
5
1 4
2 5
3 1
4 5

output
Copy
3 1 4 2 5

Note

The answer for the example contains one of several possible initial arrangements of the kittens.

The picture below shows how the cells were united for this initial arrangement. Note, that the kittens who wanted to play together on each day were indeed in adjacent cells.

 1 //F-雙向鏈表(模擬)+並查集
2 #include<bits/stdc++.h>
3 using namespace std;
4 typedef long long ll;
5 const int maxn=15*1e5+10;
6
7 int l[maxn],r[maxn],nex[maxn],root[maxn];
8
9 int findr(int x)//遞歸並查集
10 {
11     if(root[x]==x) return x;
12     return root[x]=findr(root[x]);
13 }
14
15 int main()
16 {
17     int n,u,v;
18     cin>>n;
19     for(int i=1;i<=n;i++)
20         root[i]=l[i]=r[i]=i;//初始化
21     while(n>1){
22         n--;
23         cin>>u>>v;
24         u=findr(u);
25         v=findr(v);
26         root[v]=u;//並查集合並
27         nex[r[u]]=l[v];//當前u的最右端的節點與v的最左端的節點相連
28         r[u]=r[v];//將u的最右端節點更新為v的最右端節點
29     }
30     u=l[findr(1)];//找到頭節點
31     while(u){
32         cout<<u<<" ";
33         u=nex[u];//按照連接順序輸出
34     }
35 }

 1 //F-STL list(雙向鏈表)+list拼接合並 splice函數(實現並查集的操作)
2 /*
3 list的splice函數主要是用來合並兩個list
4 splice函數是list中特有的拼接方式，splice實現了不需要拷貝的list合並，
5 即可以在常數時間內從list的一個區域拼接到另一個list的一個區域。
6 也就是說splice是一個常數時間的函數（但是也會產生其他形如list的size()問題，導致size()處理時間為O(n)不為常數)
7 l1.splice(l1.begin(),it);//(要插入的位置迭代器，要插入的元素的迭代器）
8 */
9 #include<bits/stdc++.h>
10 using namespace std;
11 typedef long long ll;
12 const int maxn=15*1e5+10;
13
14 int fa[maxn];
15
16 int find(int x)//遞歸並查集
17 {
18     return x==fa[x]?x:fa[x]=find(fa[x]);
19 }
20
21 list<int> h[maxn];
22
23 int main()
24 {
25     int n;
26     cin>>n;
27     for(int i=1;i<=n;i++){//初始化，一開始各個list里面只有自己，父節點就是自己
28         h[i].push_back(i);
29         fa[i]=i;
30     }
31     for(int i=1;i<n;i++){
32         int x,y;
33         cin>>x>>y;
34         x=find(x);
35         y=find(y);
36         fa[y]=x;//並查集節點合並
37         h[x].splice(h[x].end(),h[y]);//在h[x]的尾部插入h[y]
38     }
39     for(auto it:h[find(1)]){
40         cout<<it<<" ";
41     }
42     cout<<endl;
43 }