BJOI2015 樹的同構

2022-05-09 19:58:02 字數 1429 閱讀 2669

bzoj 4337 傳送門

這道題很顯然是樹的雜湊裸題。

有根樹的雜湊很簡單,把子節點雜湊值搞一搞(有各種搞法)就變成了本節點雜湊值。

再用map存一下就ok了。

但是這道題是無根樹,怎麼選乙個根開始深搜計算雜湊值呢?

可以使用樹的重心。

每棵樹最多有兩個重心,至少有乙個重心。

我們新建乙個節點0。

如果只有乙個重心r1,就把0和r1連起來。

如果有兩個重心r1、r2,就把r1、r2之間的邊斷開,再分別從0向r1、r2連邊。

然後從0開始計算雜湊值就好了。

1 #include2 #include3 #include4 #include5

#define ull unsigned long long

6using

namespace

std;78

intm,n;

9int f[55

];10

int hd[55],nx[105],to[105

],cnt;

1112 mapint>v;

1314

void add(int af,int

at)15

2021

void build()//

建樹 2234}

3536

int sz[55],mx[55

];37

38//

深搜計算最大子樹的重量

39void dfs(int p,int

fa)40

49 mx[p]=max(mx[p],n-sz[p]);50}

5152

intr1,r2;

5354

void weigh()//

找重心

5565 add(0,r1),add(r1,0

);66

//若有兩個重心,把它們分別與新節點相連

67if(mx[r1]==mx[r2]&&r1!=r2)add(0,r2),add(r2,0

);68

//有乙個重心

69else r2=r1;70}

7172

//深搜計算雜湊值

73 ull cal(int p,int

fa)74

86for(int i=1;i<=tp;i++)ret+=st[i]*st[i];

87return

ret;88}

8990

intmain()

91102

return0;

103 }

view code

把子節點的雜湊值的平方加到一起作為本節點的雜湊值,就能過。

把子節點的雜湊值分別乘上seed的不同次冪再加一起作為本節點的雜湊值,就wa。

不知道為什麼......

4337 BJOI2015 樹的同構

題解 樹的同構的判定 有根樹從根開始進行樹hash 先把兒子的f進行排序 f i sum num i 我沒有仔細想這樣是不是樹是唯一的。反正過了 無根樹先找到重心再作為根 因為重心最多只有兩個,複雜度仍舊o n include using namespace std define rint regi...

樹 樹的同構

給定兩棵樹t1和t2。如果t1可以通過若干次左右孩子互換就變成t2,則我們稱兩棵樹是 同構 的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點a b g的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。圖1 圖2輸入給出2棵二叉樹樹的資訊。對於每棵樹,首先在一行中給出乙個非負整數n...

樹1 樹的同構

給定兩棵樹t1和t2。如果t1可以通過若干次左右孩子互換就變成t2,則我們稱兩棵樹是 同構 的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點a b g的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。圖1圖2 現給定兩棵樹,請你判斷它們是否是同構的。輸入給出2棵二叉樹樹的資訊。對...