bzoj 4337 傳送門
這道題很顯然是樹的雜湊裸題。
有根樹的雜湊很簡單,把子節點雜湊值搞一搞(有各種搞法)就變成了本節點雜湊值。
再用map存一下就ok了。
但是這道題是無根樹,怎麼選乙個根開始深搜計算雜湊值呢?
可以使用樹的重心。
每棵樹最多有兩個重心,至少有乙個重心。
我們新建乙個節點0。
如果只有乙個重心r1,就把0和r1連起來。
如果有兩個重心r1、r2,就把r1、r2之間的邊斷開,再分別從0向r1、r2連邊。
然後從0開始計算雜湊值就好了。
1 #include2 #include3 #include4 #include5view code#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 }
把子節點的雜湊值的平方加到一起作為本節點的雜湊值,就能過。
把子節點的雜湊值分別乘上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棵二叉樹樹的資訊。對...