洛谷P1196
阿新 • • 發佈:2019-02-20
題目描述
在這次決戰中,他將巴米利恩星域戰場劃分成30000列,每列依次編號為1, 2, …,30000。之後,他把自己的戰艦也依次編號為1, 2, …, 30000,讓第i號戰艦處於第i列,形成“一字長蛇陣”,誘敵深入。這是初始陣形。當進犯之敵到達時,楊威利會多次釋出合併指令,將大部分戰艦集中在某幾列上,實施密集攻擊。合併指令為M i j,含義為第i號戰艦所在的整個戰艦佇列,作為一個整體接至第j號戰艦所在的戰艦佇列的尾部。顯然戰艦佇列是由處於同一列的一個或多個戰艦組成的。合併指令的執行結果會使佇列增大。 然而,老謀深算的萊因哈特早已在戰略上取得了主動。在交戰中,他可以通過龐大的情報網路隨時監聽楊威利的艦隊調動指令。 在楊威利釋出指令調動艦隊的同時,萊因哈特為了及時瞭解當前楊威利的戰艦分佈情況,也會發出一些詢問指令:C i j。該指令意思是,詢問電腦,楊威利的第i號戰艦與第j號戰艦當前是否在同一列中,如果在同一列中,那麼它們之間佈置有多少戰艦。
輸入樣例#1:
4
M 2 3
C 1 2
M 2 4
C 4 2
輸出樣例#1:
-1
1
分析
對於每個點,分別記錄所屬鏈的頭結點、該點到頭結點的距離以及它所在集合的大小。每次合併將y接在x的尾部,改變y頭的權值和所屬鏈的頭結點,同時改變x的尾節點。
#include<cstdio>
using namespace std;
int father[50000],b[50000],c[50000],n;
int find(int v)
{
int a;
if (father[v]==0)
return v;
else
{
a=find(father[v]);
b[v]=b[father[v]]+b[v];
father[v]=a;
return father[v];
}
}
int abs(int p)
{
if (p<0) return -p;
else return p;
}
int sss(int x,int y)
{
int l,r;
l=find(x);r=find(y);
father[l]=r;
b[l]=b[l]+c[r];
c[r]=c[l]+c[r];
}
int main()
{
int j,k;
char s;
for (int i=1;i<=50000;i++) c[i]=1;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%s%d%d",&s,&j,&k);
if (s=='M')
if (find(j)!=find(k))
sss(j,k);
else j=1;
else
if (find(j)==find(k))
printf("%d\n",abs(b[k]-b[j])-1);
else printf("-1\n");
}
}