题目本质:并查集的链式合并
解决方法1:
类似哈夫曼树,叶节点们为真点,其余造一些虚的父节点,使得dfs这棵树的时候,先进行并查合并的点一定是兄弟节点因而紧挨着被输出,巧妙达到了效果。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <ctime> 7 #include <cctype> 8 #include <climits> 9 #include <iostream> 10 #include <iomanip> 11 #include <algorithm> 12 #include <string> 13 #include <sstream> 14 #include <stack> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <vector> 19 #include <list> 20 #include <fstream> 21 #define ri readint() 22 #define gc getchar() 23 #define R(x) scanf("%d", &x) 24 #define W(x) printf("%d\n", x) 25 #define init(a, b) memset(a, b, sizeof(a)) 26 #define rep(i, a, b) for (int i = a; i <= b; i++) 27 #define irep(i, a, b) for (int i = a; i >= b; i--) 28 #define ls p << 1 29 #define rs p << 1 | 1 30 using namespace std; 31 32 typedef double db; 33 typedef long long ll; 34 typedef unsigned long long ull; 35 typedef pair<int, int> P; 36 const int inf = 0x3f3f3f3f; 37 const ll INF = 1e18; 38 39 inline int readint() { 40 int x = 0, s = 1, c = gc; 41 while (c <= 32) c = gc; 42 if (c == '-') s = -1, c = gc; 43 for (; isdigit(c); c = gc) 44 x = x * 10 + c - 48; 45 return x * s; 46 } 47 48 const int maxn = 15e4 + 5; 49 int n, fa[maxn << 1], l[maxn << 1], r[maxn << 1]; 50 51 inline int find(int v) { 52 return v == fa[v] ? v : fa[v] = find(fa[v]); 53 } 54 55 void dfs(int cur) { 56 if (!l[cur] && !r[cur]){ 57 printf("%d ", cur); 58 return; 59 } 60 if (l[cur]) dfs(l[cur]); 61 if (r[cur]) dfs(r[cur]); 62 } 63 64 int main() { 65 n = ri; 66 rep(i, 1, n) { 67 fa[i] = i; 68 } 69 rep(i, 1, n - 1) { 70 int a = ri, b = ri; 71 a = find(a), b = find(b); 72 fa[a] = fa[b] = fa[n + i] = n + i; 73 l[n + i] = a, r[n + i] = b; 74 } 75 dfs(n + n - 1); 76 return 0; 77 }
解决方法2:
正常地用数组记录链,l和r记录真实的左右顺序,并查集式的getl和getr记录这个链上的最左端和最右端,两个集合并时一接。貌似直接把常规并查集的father数组扔了……
大佬代码:
1 int n,m,i,j,k,a[150005],l[150005],r[150005],fl[150005],fr[150005],x,y; 2 int gfl(int x){if (fl[x]==x) return x;return fl[x]=gfl(fl[x]);} 3 int gfr(int x){if (fr[x]==x) return x;return fr[x]=gfr(fr[x]);} 4 int main() 5 { 6 read(n); 7 rep(i,n) 8 { 9 fl[i]=fr[i]=l[i]=r[i]=i; 10 } 11 rep(i,n-1) 12 { 13 read(x);read(y); 14 x=gfr(x);y=gfl(y); 15 r[x]=y;l[y]=x; 16 fr[x]=y;fl[y]=x; 17 } 18 x=gfl(1); 19 rep(i,n) 20 { 21 printf("%d ",x); 22 x=r[x]; 23 } 24 return 0; 25 }