nodgd家裡種了一棵樹,有一天nodgd比較無聊,就把這棵樹畫在了一張紙上。另一天nodgd更無聊,就又畫了一張。
這時nodgd發現,兩次畫的順序是不一樣的,這就導致了原本的某乙個節點u0在第一幅圖中編號為u1,在第二副圖中編號為u2。
於是,nodgd決定檢查一下他畫出的兩棵樹到底是不是一樣的。nodgd已經給每棵樹的節點都從1到n進行了編號,即每棵樹有n個節點。
如果存在乙個1到n的排列p1,p2…pn,對於第一幅圖中的任意一條邊(i,j),在第二幅圖中都能找到一條邊(pi,pj),則認為這兩幅圖中的樹是一樣的。
第一行乙個整數n,表示節點的總數。
接下來n−1行,每行兩個整數,表示第一幅圖中的每一條邊。
接下來n−1行,每行兩個整數,表示第二幅圖中的每一條邊。
如果兩幅圖的樹是一樣的,第一行輸出」yes」,接下來1行輸出乙個1到n的排列p1,p2,……,pn,兩個數之間用空格間隔。當多個排列都滿足題意時,你可以隨便輸出乙個。
如果兩幅圖的樹是不一樣的,只輸出一行」no」。
注意輸出的時候不要加引號。
31 2
2 31 3
3 2yes
1 3 2
提示【樣例解釋1】
肉眼可見,1-2-3和1-3-2顯然是一樣的兩棵樹。不過這可能不是唯一的符合題意的排列。
資料範圍:n<=100000
分析正解好像是什麼括號序列,被機房的大佬用樹hash強行卡過了。。。。。。
對於一棵樹,什麼東西與它的根節點無關呢?
反正我知道的只有重心與直徑
所以把重心找出來,直接樹hash,再從根節點往下一一對應,判斷子節點的對應點時用hash值給子節點排個序就好了
注意不能直接根據每個節點的hash值排序對應,因為如果有兩棵子樹結構相同,祖先子樹結構不同時它們是無法被區分的。
好像這是我第一次寫樹的重心
另外此題hash也有技巧,有一篇**《hash在資訊學競賽中的一類應用》
(反正我沒看,只是用了他的hash方法)
**
#include#include#include
using
namespace
std;
const
int maxn=100005
;const unsigned long
long seed=998244353
;int n,cnt[2
],ans[maxn];
unsigned
long
long ha[2
][maxn];
vector
g[2],son[2
][maxn];
int info[2][maxn],nx[2][maxn<<1],v[2][maxn<<1
];void add(int u1,int v1,int k)
bool cmp0(int a,int b)bool cmp1(int a,int b)
int yousa(int x,int f,int
k)void vr(int x,int f,int
k)
if(k==0
)sort(son[k][x].begin(),son[k][x].end(),cmp0);
if(k==1
)sort(son[k][x].begin(),son[k][x].end(),cmp1);
ha[k][x]=1
;
for(int i=son[k][x].size()-1;i>=0;i--)ha[k][x]=ha[k][x]*seed^ha[k][son[k][x][i]];
ha[k][x]*=seed*seed;
}void solve(int a,int b)
intmain()}}
puts("no
");}
CSP2019樹的重心
題解 csp2019d2t3 首先我們要明確乙個性質,那就是對於一棵樹的任何乙個節點來說,如果這個點不是重心,那麼這棵樹的重心就一定在這個節點的以重兒子為根節點的子樹裡 證明顯而易見,因為該點不是重心所以siz 重兒子 一定大於 lfloor frac rfloor 另外還有乙個重心的定義 重心所有...
CSP2019 樹的重心
點這裡看題目。原來資料的奇怪結尾就可以拿來判斷特徵呀 太簡單就不說了。考慮完全二叉樹怎麼做。這裡需要注意一點,就是 n 262143 2 1 也就是說,資料實際上就是一棵滿二叉樹。由於滿二叉樹具有極強的對稱性,我們不難想到這樣解決 首先,答案一定包含 frac rt 其中 rt 是樹的根。考慮根的左...
CSP2019 樹的重心(樹的重心 倍增 換根)
當年我做這道題時還太嫩了,只能想到暴力。其實如果會了更高的科技這道題只要稍微對暴力優化一下就能ac 我也不會含淚75pts了 廢話不說了,暴力的思路就是列舉每一條邊然後求兩個子樹的重心。直接求重心的複雜度是 o n 的,我們考慮優化到 o log 我們想要求以 x 為根的子樹的重心,首先有個引理 這...