HDU5963 朋友 博弈

2021-08-08 06:11:25 字數 1195 閱讀 7955

problem description

b君在圍觀一群男生和一群女生玩遊戲,具體來說遊戲是這樣的:

給出一棵n個節點的樹,這棵樹的每條邊有乙個權值,這個權值只可能是0或1。 在一局遊戲開始時,會確定乙個節點作為根。接下來從女生開始,雙方輪流進行 操作。

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

當一方無法操作時(即所有邊的邊權均為0),另一方就獲得了勝利。

如果在雙方均採用最優策略的情況下,女生會獲勝,則輸出「girls win!」,否則輸 出「boys win!」。

為了讓遊戲更有趣味性,在每局之間可能會有修改邊權的操作,而且每局遊戲指 定的根節點也可能是不同的。

具體來說,修改邊權和進行遊戲的操作一共有m個,具體如下:

∙「0 x」表示詢問對於當前的樹,如果以x為根節點開始遊戲,哪方會獲得勝利。

∙「1 x y z 」表示將x和y之間的邊的邊權修改為z。

b君當然知道怎麼做啦!但是他想考考你。

input

包含至多5組測試資料。

第一行有乙個正整數,表示資料的組數。

接下來每組資料第一行,有二個空格隔開的正整數n,m,分別表示點的個數,操 作個數。保證n,m< 40000。

接下來n-1行,每行三個整數x,y,z,表示樹的一條邊。保證1

結論很簡單,與根相連的邊權值為1的數量為奇數則女孩贏,否則男孩贏

#include 

using

namespace

std;

const

int n = 50000 + 10, inf = 0x3f3f3f3f;

struct edge

g[n*2];

int cnt, head[n];

void init()

void add_edge(int v, int u, int cost)

void update(int x, int y, int cost)

}int query(int x)

int main()

int opt;

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

else}}

return

0;}

HDU 5963 朋友 思維 博弈

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

HDU 5963 朋友 樹上博弈

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

HDU 5963 朋友 (樹上博弈,思維)

題面 思路 我們通過推理應該知道如下性質 那麼我們只需要維護出每乙個節點邊權為1的出邊個數即可,偶數個boys 贏,奇數個girls贏。關於第二個性質的證明 include using namespace std typedef pairpii const int maxn 40000 10 def...