題目描述 description
公元五八○一年,地球居民遷移至金牛座α第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。
宇宙歷七九九年,銀河系的兩大軍事集*在巴公尺利恩星域爆發戰爭。泰山壓頂集**宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集*點名將楊威利組織麾下三萬艘戰艦迎敵。
楊威利擅長排兵布陣,巧妙運用各種戰術屢次以少勝多,難免恣生驕氣。在這次決戰中,他將巴公尺利恩星域戰場劃分成30000列,每列依次編號為1, 2, …, 30000。之後,他把自己的戰艦也依次編號為1, 2, …, 30000,讓第i號戰艦處於第i列(i = 1, 2, …, 30000),形成「一字長蛇陣」,誘敵深入。這是初始陣形。當進犯之敵到達時,楊威利會多次發布合併指令,將大部分戰艦集中在某幾列上,實施密集攻擊。合併指令為m i j,含義為讓第i號戰艦所在的整個戰艦佇列,作為乙個整體(頭在前尾在後)接至第j號戰艦所在的戰艦佇列的尾部。顯然戰艦佇列是由處於同一列的乙個或多個戰艦組成的。合併指令的執行結果會使佇列增大。
然而,老謀深算的萊因哈特早已在戰略上取得了主動。在交戰中,他可以通過龐大的情報網路隨時監聽楊威利的艦隊調動指令。
在楊威利發布指令調動艦隊的同時,萊因哈特為了及時了解當前楊威利的戰艦分布情況,也會發出一些詢問指令:c i j。該指令意思是,詢問電腦,楊威利的第i號戰艦與第j號戰艦當前是否在同一列中,如果在同一列中,那麼它們之間布置有多少戰艦。
作為乙個資深的高階程式設計員,你被要求編寫程式分析楊威利的指令,以及回答萊因哈特的詢問。
最終的決戰已經展開,銀河的歷史又翻過了一頁……
輸入描述 input description
輸入檔案galaxy.in的第一行有乙個整數t(1<=t<=500,000),表示總共有t條指令。
以下有t行,每行有一條指令。指令有兩種格式:
1. m i j :i和j是兩個整數(1<=i , j<=30000),表示指令涉及的戰艦編號。該指令是萊因哈特竊聽到的楊威利發布的艦隊調動指令,並且保證第i號戰艦與第j號戰艦不在同一列。
2. c i j :i和j是兩個整數(1<=i , j<=30000),表示指令涉及的戰艦編號。該指令是萊因哈特發布的詢問指令。
輸出描述 output description
輸出檔案為galaxy.out。你的程式應當依次對輸入的每一條指令進行分析和處理:
如果是楊威利發布的艦隊調動指令,則表示艦隊排列發生了變化,你的程式要注意到這一點,但是不要輸出任何資訊;
如果是萊因哈特發布的詢問指令,你的程式要輸出一行,僅包含乙個整數,表示在同一列上,第i號戰艦與第j號戰艦之間布置的戰艦數目。如果第i號戰艦與第j號戰艦當前不在同一列上,則輸出-1。
樣例輸入 sample input
m 2 3
c 1 2
m 2 4
c 4 2
樣例輸出 sample output
-1資料範圍及提示 data size & hint
第一列第二列
第三列第四列
初始時m 2 3
c 1 2
1號戰艦與2號戰艦不在同一列,因此輸出-1
m 2 4
c 4 2
4號戰艦與2號戰艦之間僅布置了一艘戰艦,編號為3,輸出1
【解題思路】
我一直認為這個題目特別的浮誇,因為題目那麼長卻並沒有什麼卵用,歸結起來,這個題就是並查集的應用
定義三個陣列f,s,sum,f表示根,s表示當前物品在該集合的位置,sum表示當前根節點下的數的數目
1varn,i,f1,f2,a,b:longint;
2ch:char;
3 sum,f,s:array [0..30000] of
longint;
4function
getfather(v:longint):longint;
5var
p:longint;
6begin
7if f[v]=v then
exit(v);
8 p:=getfather(f[v]);
9 s[v]:=s[f[v]]+s[v];//路徑壓縮時改變位置
10 f[v]:=p;//路徑壓縮
11 getfather:=f[v];
12end;13
begin
14 assign(input,'
galaxy.in');
15 assign(output,'
galaxy.out');
16reset(input);
17rewrite(output);
18readln(n);
19for i:=1
to30000
dobegin s[i]:=0;sum[i]:=1;f[i]:=i;end;//初始化
20for i:=1
to n do
21begin
22read(ch);
23readln(a,b);
24 f1:=getfather(a);
25 f2:=getfather(b);
26if ch='m'
then
27begin
28 s[f1]:=sum[f2]+s[f1];
29 sum[f2]:=sum[f2]+sum[f1];
30 f[f1]:=f2;
31end;32
if ch='c'
then
33if f1<>f2 then writeln(-1) else writeln(abs(s[a]-s[b])-1
);34
end;
35close(input);
36close(output);
37end.
codevs1540 銀河英雄傳說
我們的征途是星辰大海 銀英傳 這才是題目 思路 加權並查集 維護f i t i cnt i cnt i i在當前佇列中後面有多少元素 f i i所在集合標誌元素 佇列底元素 注意在未執行find i 操作時,f i 不一定為i真正的底 t i i所在佇列頂元素 t i 僅在merge更新不再是隊底的...
COdevs 1540 銀河英雄傳說
source 2002年noi全國競賽 時間限制 1 s 空間限制 256000 kb 題目等級 大師 master 公元五八 一年,地球居民遷移至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集 在巴公尺利恩星域爆發戰爭...
銀河英雄傳說
公元五八 一年,地球居民遷至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集 在巴公尺利恩星域爆發戰爭。泰山壓頂集 宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集 點名將楊威利組織麾下三萬艘戰艦迎敵。楊威利擅長排兵布...