Asya And Kittens(并查集)(连接)

Asya loves animals very much. Recently, she purchased n kittens, enumerated them from 1 and n and then put them into the cage. The cage consists of one row of n cells, enumerated with integers from 1 to n from left to right. Adjacent cells had a partially transparent partition wall between them, hence there were n−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 i, Asya:

Noticed, that the kittens xi and yi, 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 n−1 days the cage contained a single cell, having all kittens.

For every day, Asya remembers numbers of kittens xi and yi, 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 n cells.

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

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

It’s guaranteed, that the kittens xi and yi were in the different cells before this day.

Output
For every cell from 1 to n print a single integer — the index of the kitten from 1 to n, 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
5
1 4
2 5
3 1
4 5
Output
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.

一开始完全没有思路,看了博客想了三天才想出来的。
附大佬博客:https://blog.csdn.net/Link_Ray/article/details/87904632

做法有很多种。我看的都是用两个并查集维护树的起点和终点,再用一个数组r维护i的下一个数。
要开两个数组存根节点,一个指向起点,一个指向终点。

读入的两个数,第一个数根节点是目前集合的终点(这样把第二个数的集合跟在第一个数的集合的后面就行了),第二个数根节点是目前集合的起点(这样就可以把第一个数的集合跟在这个集合的前面)。然后把终点与起点通过r【】相连,就完成了。

最后输出的时候随便找一个数(所以就选择最后一次的读入数啦)寻找集合的起点,然后通过r【】依次输出就行了。

贴上我的代码(根据大佬的思路一下就a了,代码超级简介,比学长的简单易懂多了(逃))。

#include<iostream>
using namespace std;
int f1[150020];int f2[150090];int r[150080];


int find1(int x){
	return x==f1[x]?x:f1[x]=find1(f1[x]);
}

int find2(int x){
	return x==f2[x]?x:f2[x]=find2(f2[x]);
}

int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		f1[i]=f2[i]=i;
	}
	int t=n-1;
	int u,v;
	while(t--){
		int n1,n2;scanf("%d%d",&u,&v);
		u=find1(u);v=find2(v);
		r[u]=v;
		f1[u]=v;f2[v]=u;
	}
	int tem=find2(v);
	printf("%d",tem);
	tem=r[tem];
	for(int i=1;i<n;i++){
		printf(" %d",tem);
		tem=r[tem];
	}
	
}

其他思路的待我有时间再学。

猜你喜欢

转载自blog.csdn.net/weixin_43806345/article/details/88750358