NKOJ 1206 【NOI2002 Day1 T1】银河英雄传说
思路:和NKOJ 2281一样
实现方法
- 移动操作完全一样。
- 计算操作的区别在于,一个是直接输出到根节点的距离,另一个实际上是前缀和思想,用 \(x\) 到根的距离减去 \(y-1\) 到根的距离,就是 \(x\sim y\) 之间的距离。
代码
#include<cstdio>
#include<iostream>
using namespace std;
int n;
int f[800005];
int hgt[800005];
int dis[800005];
int getf(int x){
if(f[x]!=x){
int t=f[x];
f[x]=getf(f[x]);
dis[x]+=dis[t];
}
return f[x];
}
void merge(int x,int y){
int fx=getf(x);
int fy=getf(y);
if(fx!=fy){
f[fx]=fy;
dis[fx]+=hgt[fy];
hgt[fy]+=hgt[fx];
hgt[fx]=0;
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=800000;i++) f[i]=i,hgt[i]=1;//注意点1
while(n--){
char op;
int x,y;
cin>>op>>x>>y;
if(op=='M'){
merge(x,y);
}
else{
if(getf(x)==getf(y)){
cout<<abs(dis[y]-dis[x])-1<<"\n";
}
else cout<<"-1\n";
}
}
return 0;
}
注意事项
- 数组初始化不要越界。
- 开了
longlong
反而见祖宗(TLE) 。
- 用了
cin
就全盘都用 cin
并加上 ios
。