1. 程式人生 > >Codeforces 1131 F. Asya And Kittens-雙向鏈表(模擬或者STL list)+並查集(或者STL list的splice()函數)-對不起,我太菜了。。。

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

part 頭節點 possible after out unit pac include them

F. Asya And Kittens 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 nn kittens, enumerated them from 11 and nn and then put them into the cage. The cage consists of one row of

nn cells, enumerated with integers from 11 to nn from left to right. Adjacent cells had a partially transparent partition wall between them, hence there were n1n−1 partitions originally. Initially, each cell contained exactly one kitten with some number.

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

ii, Asya:

  • Noticed, that the kittens xixi and yiyi, located in neighboring cells want to play together.
  • 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 n1n−1 days the cage contained a single cell, having all kittens.

For every day, Asya remembers numbers of kittens xixi and yiyi, who wanted to play together, however she doesn‘t remember how she placed kittens in the cage in the beginning. Please help her and find any possible initial arrangement of the kittens into nn cells.

Input

The first line contains a single integer nn (2n1500002≤n≤150000) — the number of kittens.

Each of the following n1n−1 lines contains integers xixi and yiyi (1xi,yin1≤xi,yi≤n, xiyixi≠yi) — indices of kittens, which got together due to the border removal on the corresponding day.

It‘s guaranteed, that the kittens xixi and yiyi were in the different cells before this day.

Output

For every cell from 11 to nn print a single integer — the index of the kitten from 11 to nn, who was originally in it.

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.

技術分享圖片

題意就是給你兩個數合並的順序讓你構造序列。

一開始沒想起來,以為是單鏈表,突然想到要有前驅,就想到雙向鏈表了,但是一直卡D,沒時間了,這是一個過的比D多的F題。。。

思路就是雙向鏈表+並查集,具體的代碼寫了註釋。

兩種代碼,一個是模擬的雙向鏈表+並查集,一個是用STL的list+list的splice()函數。

看的某大佬群裏大佬的代碼。

代碼一:

 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 }

想晚了,對不起,比賽的時候沒出來這道題。。。

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