Codeforces Round #541 (Div. 2) F. Asya And Kittens

链接:https://codeforces.com/contest/1131/problem/F

题意:有一个由1~n构成的长度为n的序列,相邻两数不连通,经过n-1次操作,整个序列是连通的,每次操作只能将相邻两块进行连通,给出每次操作时相邻两块中的数字,输出原序列

思路:并查集,根据大佬的题解,用类似链表的方法进行连接

代码:(转载自https://www.cnblogs.com/ZERO-/p/10426473.html)

 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 }

 备注:第一次做并查集的题目,感觉对递归和链表的要求挺大的,感谢这篇博客->https://blog.csdn.net/liuyang981122/article/details/81530014 ,写的非常清晰明白,留待以后继续学习

猜你喜欢

转载自www.cnblogs.com/harutomimori/p/10433173.html