实验任务
给定一个\(1\sim N\)的全排列,给出\(M\)对可以交换的位置\((A_i,B_i)\)。每一次,你可以选择一对位置,交换其位置上的数值。不限制操作次数,请问经过交换后,字典序最大的全排列是多少(字典序的定义请参考)。
数据输入
第一行输入包括两个整数,\(N\)和\(M\ (1\leq N,M\leq 20000)\)。第二行输入包括\(N\)个整数,表示\(1\sim N\)的全排列。接下去\(M\)行,每行包括两个整数\(A_i,B_i\ (1\leq A_i,B_i\leq N,A_i\neq B_i)\),表示序列中\(A_i\)和\(B_i\)位置上的数可以交换。
数据输出
出入\(N\)个整数,表示最大字典序的序列。
输入示例 | 输出示例 |
---|---|
5 3 1 5 4 2 3 1 3 3 5 2 4 |
4 5 3 2 1 |
源代码(dfs)
1 |
|
源代码(并查集)
1 |
|
设计思路与复杂度分析
位置A和B可以互换,位置B和C可以互换,则位置A和C也可以互换。先将可以互相交换的数都放入同一个集合,然后将同一个集合的数进行逆序排序,放入原来的集合对应的位置即可得到解。
查找集合的方法就不唯一了:
- 将序列看做深林,每一个交换集看做一棵树,则使用\(dfs\)或者\(bfs\)遍历即可得到每一颗树;
- 既然是集合问题,自然可以使用并查集实现。
以上算法都可以在\(O(n\times logn)\)时间复杂度内实现。