因爲沒有壓縮路徑,因此訪問每一個成員的根會十分的慢,因此十分容易超時
(因爲超時,所以不知道對不對……)
#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;
}