poj1182食物鏈 並查集 向量偏移

2022-05-14 02:48:14 字數 1474 閱讀 3270

搞了好久才弄明白。。。之前學並查集從來沒想過能這麼用,並查集+向量偏移!!!

與一般並查集只開乙個father陣列不同,還要開乙個ralation陣列用來記錄子節點與父節點的關係,對於此題,顯然每個點對應根節點可能有三種關係,我用ralation[i]=0記為i與根節點是同類,relation[i]=1記為i被根節點吃,relation[i]=2記為i吃根節點。

難點在於合併兩個結點時如何更新節點對應的關係值(即relation[i],比如兩個節點有不同的父節點,分別對應自己的父節點有乙個關係值,而此時這兩個點也有關係,需要合併,那麼某棵樹上的關係值很可能全都要改)。

下面就是合併過程,結合圖分析,向量思維。如圖:

圖一                                         圖二

圖一:表示m和n分別為兩棵樹的根節點,對應的關係為0,即與自己是同類。a對m的關係為1,即被m吃,同理b吃n;記向量m->a=1;n->b=2;

圖二:加入a和b的關係,a被b吃,即圖中的向量a->b=2;此時要合併兩棵樹,即要求n對m的關係(我們定為n樹合到m樹),即向量m->n的值。

根據向量的運算法則,m->n = m->a + a->b + b->n = m->a + a->b – n->b

即relation[n]=(relation[a]+(d-1)-relation[b]+3)%3;  括號中加3是為了防止出現負號,對3取模是因為只有0,1,2三種關係。

然後求更新relation[b](即m->b的值)就簡單了,還是向量的思想,m->b = m->n +n->b,同上relation[b]=(relation[n]+relation[b])%3;  注意**中我放到了getfather裡面進行這一步。

全部更新完之後圖就變成了這樣

再配合**看應該就很好理解了。。

1 #include2 #include3

const

int maxn=50010;4

int f[maxn],r[maxn]; //

f為父親陣列,r為關係陣列

5int

n,m,u,v;

6int

d,ans;

7void init() //

初始化814}

1516

int gf(int x) //

getfather

1724

return

f[x];25}

2627

void uni(int a,int b) //

合併28

36else40}

4142

intmain()

4355 printf("

%d\n

",ans);

5657 }

再看這兩道題加以練習鞏固。

POJ 1182 食物鏈(向量偏移並查集)

題目大意 中文題,很容易就理解。思路 偶然間看到某大佬的這個 向量偏移的並查集的方法,就拿來做例題了。向量偏移,具體 已經不可考究了,不知是那位神仙發現的這種方法,就是說,把並查集的關係也加上權值 似乎是帶權並查集的另一種稱呼 具體的學習部落格見 以後這就是一種思路了,用向量的思路來理解並查集,話說...

POJ 1182 食物鏈 並查集

此題利用並查集解決。對於每只動物i建立3個元素i a,i b,i c,並用這3 n個元素建立並查集。1 i x表示 i屬於種類x 2 並查集你的每一組表示組內所有元素代表的情況同時發生或不發生。對於每一條資訊,只需要按照下列操作即可 1.第一種 x,y同類,合併x a和y a x b和y b x c...

POJ 1182 食物鏈 (並查集)

食物鏈time limit 1000ms memory limit 10000k total submissions 48713 accepted 14202 description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編...