NOI2002 銀河英雄傳說

2022-05-02 06:30:12 字數 1074 閱讀 7487

這是一道帶權並查集的題目。

首先,按照題目要求,我們可以很容易的想到用並查集來實現。但是我們會發現,如果只用並查集記錄佇列的合併情況,那麼就無法滿足c操作,所以我們需要在維護並查集的同時,維護每個結點的資訊。

這道題目需要查詢是否在乙個佇列中,也就是是否在乙個集合中,是並查集的基本操作,寫乙個find函式就可以了。但是第二個要求是乙個並查集中兩個結點的距離,那麼我們就需要乙個d陣列,記錄結點i到fa[i]的距離,那麼詢問的時候就可以輸出abs(d[x]-d[y])-1。

那接下來的問題就是怎麼維護這個d陣列呢?首先我們可以明確的一點是需要在查詢、合併並查集的時候維護,那我們想一想,並查集在合併的時候,會把乙個並查集的頭結點和另乙個並查集的頭結點合併,但是題目的要求是,把乙個並查集的頭部接到另乙個並查集的尾部,所以我們就需要知道並查集的大小,我們用siz表示,這樣的話每次合併我們就只需要做和就可以了,因為結點到新佇列頭結點的距離=當前節點原來到隊頭的距離+新並查集的大小。如果不理解的話,我們可以看一下下面的圖:

當我們要合併x和y的時候,我們會把兩個並查集的頭結點連線起來,所以x中子節點的d就可以表示為y的大小+它到x頭結點的距離。

下面是ac**:

#include#define r register int

#define m 500500

using

namespace

std;

intt,fa[m],d[m],siz[m];

//d 表示飛船i到隊頭的距離 siz 表示飛船所在並查集的大小

char

ch;inline

int find(int

x)

return

fa[x];

}inline

void add(int x,int

y)inline

int query(int x,int y)

intmain()

return0;

}

NOI2002 銀河英雄傳說

noi2002 day1 t1 公元5801年,地球居民遷移至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集團在巴公尺利恩星域爆發戰爭。泰山壓頂集團派宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集團點名將楊威利組織...

NOI 2002 銀河英雄傳說

有 n 列戰場,每一列一開始只有乙個戰艦,編號就是對應的戰場編號。有 m 次操作 注意每一列戰場的戰艦都是排成一列的。帶偏移量的並查集。記錄 d x 表示 x 到所在列頭的一段上共有多少個戰艦。記錄 sz x 表示 x 所在的一列有多少個戰艦。為了保證複雜度,我們在做的時候還是要路徑壓縮。但是 d ...

NOI2002 銀河英雄傳說

公元五八 一年,地球居民遷移至金牛座 第二行星,在那裡發表銀河聯邦創立宣言,同年改元為宇宙歷元年,並開始向銀河系深處拓展。宇宙歷七九九年,銀河系的兩大軍事集 在巴公尺利恩星域爆發戰爭。泰山壓頂集 宇宙艦隊司令萊因哈特率領十萬餘艘戰艦出征,氣吞山河集 點名將楊威利組織麾下三萬艘戰艦迎敵。楊威利擅長排兵...