有N个结点
一次 I u v 操作表示把结点u的父结点设为v,距离为|u-v|%1000.输入保证执行指令前u没有父结点
一次E u 操作表示询问u到根结点的距离
O操作表示结束
解题思路:
因为题目只查询结点到根结点的距离,所以每棵树除了根结点不能换之外,其他结点的位置可以任意改变,,这恰好符合并查集的特点,但是需要记录附加信息。如果记录每个结点到根的距离,那么每次I操作都要更新很多结点的信息,时间复杂度难以保证,因此考虑记下每个结点到父结点的距离为d[i],然后在路径压缩时维护这个d数组,即到根结点的距离等于各枝距离之和。因为合并操作指定了父结点和子结点,所以不能使用启发式合并
完整代码如下
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define MAXSIZE 20010
int par[MAXSIZE];
int depth[MAXSIZE];
int u,v;
void Init()
{
int i;
for(i=0;i<MAXSIZE;i++)
{
par[i]=i;
depth[i]=0;
}
}
void InsertNode()
{
par[u]=v;
depth[u]=abs(v-u);
}
int QueryNode()
{
int ret=0;
while(par[u]!=u)
{
ret+=depth[u];
u=par[u];
}
return ret;
}
int main()
{
int T;
int i;
cin>>T;
while(T--)
{
int n;
char cmd[10];
cin>>n;
Init();
for(i=0;i<n;i++)
{
cin>>cmd;
if(cmd[0]=='O')
{
break;
}
else if(cmd[0]=='I')
{
cin>>u>>v;
InsertNode();
}
else if(cmd[0]=='E')
{
cin>>u;
cout<<QueryNode()<<endl;
}
}
}
return 0;
}