题目链接: Cube Stacking
题意
M a b 代表把包含第一个数字的栈放到包含第6个数字上面的栈的上方。 开始的时候栈从1 - N标号,每个栈里的数字是它的标号。如果输入C a 代表让你输出 a 数字下方的数字有多少个。
思路
想了挺长时间,发现大部分题解还是想的有些麻烦。这也是道经典的带权并查集。under【i】代表第i 个数字下方有多少个数字,因此最终的答案就是under数组. 我们一般来说应用并查集的val【】数组记录的是此节点到根节点的距离,此题也是一样的,sum【i】代表 i 节点下的节点有多少个。 因此当我们执行combine操作的时候,under[fa] = sum[fb] 就代表 fa 节点的下方的数字的个数有 sum[fb]个。 这道题只不过是多了个sum[]数组,用并查集挺巧妙的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include <iostream> #include <algorithm> #include <string> using namespace std; int sum[100001],f[100001],under[100001]; int Find(int x) { if(x != f[x]) { int t = f[x]; f[x] = Find(f[x]); under[x] += under[t]; } return f[x]; } void combine(int a,int b) { int fa = Find(a); int fb = Find(b); f[fa] = fb; under[fa] = sum[fb]; sum[fb] += sum[fa]; } int main() { int n,a,b; string s; cin >> n; for(int i = 1; i <= n; ++i) { f[i] = i; under[i] = 0; sum[i] = 1; } for(int i = 1; i <= n; ++i) { cin >> s ; if(s[0] == 'M') { cin >> a >> b; combine(a,b); } else{ cin >> a; int fa = Find(a); cout << under[a] << endl; } } }
|