HDU 5963 遊戲 博弈 規律

2022-05-09 18:18:01 字數 1395 閱讀 5618

題意是:

一群男生和一群女生玩遊戲:給出一棵 n 個節點的樹,這棵樹的每條邊有乙個權值 0 或 1。 在一局遊戲開始時,確定乙個節點作為根。從女生開始,雙方輪流進行操作。

當一方操作時,要先選擇乙個不為根且到其父親的邊權為 1 的點,然後找出這個點到根節點的簡單路徑,將路徑上所有邊的權值翻轉(即 0 變成 1,1 變成 0 )。

當一方無法操作時(即所有邊的邊權均為 0),另一方就獲得了勝利。雙方均採用最優策略,若女生獲勝,則輸出 「girls win!」,否則輸出「boys win!」。

每局之間可能會有修改邊權的操作,且每局遊戲指定的根節點也可能是不同的。

首先要明確結果只有兩種,當運算元為奇數時女生獲勝,當運算元為偶數時男生獲勝。

一、這種情況下需要經過兩次操作才能將所有權值置 0 ;二、

這種情況下需要經過一次或三次操作才能將所有權值置 0 ;

三、這種情況下需要經過兩次或四次操作才能將所有權值置 0 ;四、

這種情況下需要經過三次或五次操作才能將所有權值置 0。

上述四種情況的結論是只要進行操作就一定會出現的,不一定要特別採用最優策略,也就是說情況出現後先手與後手的輸贏已經確定,雙方只要按規則操作即使想可以改變結果也

無法做到,其實應該還有第五種情況,就是都為 0 的情況,這種情況下需要零次操作才能將所有權值置 0。

發現,當與根結點相連的邊權和為偶數時需要且一定經過偶數次操作才能將所有權值置 0,當與根結點相連的邊權和為奇數時需要且一定經過奇數次操作才能將所有權值置 0。

開始時打算用 40000*40000 的 bool 陣列去存,但還是超記憶體了……

錯誤**:

1 #include 2

using

namespace

std;

3bool p[40010][40010];4

intmain()518

for(int i = 0; i < m; ++i)

1927

else

2836}37

}38return0;

39 }

view code

改成 vector 陣列才過了

**如下:

1 #include 2

using

namespace

std;

3 vector p[40010];4

int num[40010];5

intmain()624

}25for(int i = 0; i < m; ++i)

2640

if(it1==p[x].end() && z==1)41

47}48else

4954}55

}56return0;

57 }

view code

HDU5963 朋友 博弈

problem description b君在圍觀一群男生和一群女生玩遊戲,具體來說遊戲是這樣的 給出一棵n個節點的樹,這棵樹的每條邊有乙個權值,這個權值只可能是0或1。在一局遊戲開始時,會確定乙個節點作為根。接下來從女生開始,雙方輪流進行 操作。當一方操作時,他們需要先選擇乙個不為根的點,滿足該點...

HDU 5963 朋友 思維 博弈

題意 中文題。思路 考慮和根相連的一條樹鏈,如果這條樹鏈上和根相連的那條邊權值為1,那麼最終在該鏈上的操作次數要為奇數次才能使得和根相連的邊的權值變為0 因為不論選擇該條樹鏈上哪個點,此邊的權值總會翻轉 同理可得和根相連的邊若初始權值為0要操作偶數次。而無論兩個人怎麼操作,都不會改變這些根的直連邊變...

HDU 5963 朋友 樹上博弈

給定一棵樹,樹中每一條邊有乙個權值為0或者1,每次遊戲需要找到乙個點,滿足該點到其父親的邊權為1,然後找到這個點到根節點的簡單路徑,將路徑上所有邊的權值翻轉。當一方無法操作時,另一方就獲勝。每次遊戲有m個操作,0 x表示指定x為根節點,要求輸出誰會贏 1 x y z表示將x和y之間的邊修改為z。本題...