题解:P5092 [USACO04OPEN] Cube Stacking
program_xwl · · 题解
这题其实可以不用带权并查集,我的思路是并查集+链表。思路非常容易理解,但时间比较慢。
思路:
众所周知,链表的插入是
我们用
移动操作:
我们先找到
统计操作:
直接掉用
这种方法虽然好理解,但时间很慢,可以借助代码理解一下。
代码:
#include <bits/stdc++.h>
using namespace std;
int T,tree[100005],it_down[100005],nt[100005];
int find(int x)
{
if(tree[x] == x) return x;
return tree[x] = find(tree[x]);
}
void unionn(int x,int y)
{
x = find(x);
y = find(y);
if(x != y) tree[x] = y;
return;
}
int main(void)
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
for(int i = 1;i <= 30000;i++) tree[i] = i;//题目不告诉我们n是多少,干脆全初始化了。
memset(nt,-1,sizeof(nt));//初始化单链表
while(T--)
{
char op;
int x,y;
cin >> op;
if(op == 'M')
{
cin >> x >> y;
int top_high,top;
for(int i = find(y);;i = nt[i])
{
if(nt[i] == -1)//这个是链表尾了
{
top_high = it_down[i]+1;//记录立方柱最高的高度
top = i;//记录立方柱最高方块的编号
break;
}
}
for(int i = find(x);;i = nt[i])//全部加上
{
it_down[i] += top_high;
if(nt[i] == -1) break;
}
nt[top] = find(x);//拼接链表
unionn(x,y);//合并并查集
}else
{
cin >> x;
cout << it_down[x] << '\n';
}
}
return 0;
}