因为没有压缩路径,因此访问每一个成员的根会十分的慢,因此十分容易超时
(因为超时,所以不知道对不对……)
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
ifstream fin("galaxy.in");
ofstream fout("galaxy.out");
#define cin fin
#define cout fout
struct Tnode
{
int f,l,fa;
};
Tnode t[30001];
int n;
int u_f(int x) //找出战舰队列中的头·
{
int root=x;
while(t[root].fa!=root) root=t[root].fa;
/* while(fa[x]!=x)
{
int y=fa[x];
fa[x]=root;
x=y;
}
*/
return root;
}
bool _ch(int x,int y) //判断是否在同一列
{
int lx=t[x].l;
int fx=t[x].f;
if(fx==y) return true;
do
{
if(lx==y)
return true;
lx=t[lx].fa;
} while(lx!=fx);
return false;
}
int _getans(int x,int y) 找出中间有几个站舰队
{
int ans=0;
int lx=t[x].l;
int fx=t[x].f;
if(lx==y)
//如果最后一个就是y,则找出最后一个与x中间的个数 {
while(t[lx].fa!=x || t[lx].fa!=y) ans++;
return ans;
}
if(t[x].fa==y || t[y].fa==x) return 0;
//如果两个之中有一个是另一个的前面那个,则直接返回0
while(t[lx].fa != fx)
{
if(t[lx].fa==y || t[lx].fa==x || ans>0) //如果找到了x或y,则开始累加
ans++;
else if(ans>0 && (t[lx].fa==y || t[lx].fa==x)) //如果又找到x或y并且已经开始累加,则停止循环
break;
lx=t[lx].fa;
}
ans--; //前面多加了一次
return ans;
}
void _change(int x,int y) //改变数据的头和尾
{
t[t[x].f].fa=t[y].l;
t[y].l=t[x].l;
t[x].f=t[y].f;
int fx=u_f(x);
int lx=t[x].l;
t[fx].f=t[x].f;
t[fx].l=t[x].l;
while(lx!=fx)
{
t[lx].f=t[x].f;
t[lx].l=t[x].l;
lx=t[lx].fa;
}
}
int main()
{
cin>>n;
for(int i=1;i<=30000;i++)
t[i].f=t[i].l=t[i].fa=i;
for(int i=0;i<n;i++)
{
char c;
int x,y;
cin>>c>>x>>y;
int fx=u_f(x);
int fy=u_f(y);
if(c=='M')
if(fx!=fy)
_change(x,y);
if(c=='C')
if(_ch(x,y))
cout<<_getans(x,y)<<endl;
else cout<<-1<<endl;
/*
==用于调试==
for(int i=1;i<=6;i++)
cout<<"i:"<<i<<" fa:"<<t[i].fa\
<<" first:" <<t[i].f<<" last:"\
<<t[i].l <<endl;
cout<<endl;
*/
}
return 0;
}