4337 BJOI2015 樹的同構

2022-05-31 05:33:22 字數 1815 閱讀 2132

題解:

樹的同構的判定

有根樹從根開始進行樹hash

先把兒子的f進行排序

$f[i]=\sum_^ +num[i]$(我沒有仔細想這樣是不是樹是唯一的。。。反正過了)

無根樹先找到重心再作為根

因為重心最多只有兩個,複雜度仍舊o(n)

**:

#include using

namespace

std;

#define rint register int

#define il inline

#define rep(i,h,t) for (int i=h;i<=t;i++)

#define dep(i,t,h) for (int i=t;i>=h;i--)

#define me(x) memset(x,0,sizeof(x))

#define ll long long

#define mep(x,y) memcpy(x,y,sizeof(y))

#define mid ((h+t)>>1)

#define ull unsigned ll

namespace

io template

void read(t &x)

char sr[1

<<24],z[20]; int z,c=-1

; template

void

wer(t x)

il void wer1()

il void wer2()

template

il void maxa(t &x,t y)

template

il void mina(t &x,t y)

template

il t max(t x,t y)

template

il t min(t x,t y)

};using

namespace

io;const

int n=100

;int

head[n],n,m,l,num[n],f[n];

struct

ree[n*2

];bool q[1100

];int

zs[n];

ull son[n][n],ans[n],g[n];

il void arr(int x,int

y)void fdrt(int x,int

y) }

if (n-num[x]>f[x]) f[x]=n-num[x];

}void dfs(int x,int

y) }

sort(son[x]+1,son[x]+cnt+1

); ull now=0

; rep(i,

1,cnt) now=now+son[x][i]*zs[i];

now+=num[x];

g[x]=now;

}int

main()

rep(j,

1,m)

fdrt(

1,0);

int ma=1e9;

rep(i,

1,n) ma=min(ma,f[i]);

rep(i,

1,n)

if (f[i]==ma)

}rep(i,

1,m)

rep(j,

1,m)

if(ans[j]==ans[i])

return0;

}

BJOI2015 樹的同構

bzoj 4337 傳送門 這道題很顯然是樹的雜湊裸題。有根樹的雜湊很簡單,把子節點雜湊值搞一搞 有各種搞法 就變成了本節點雜湊值。再用map存一下就ok了。但是這道題是無根樹,怎麼選乙個根開始深搜計算雜湊值呢?可以使用樹的重心。每棵樹最多有兩個重心,至少有乙個重心。我們新建乙個節點0。如果只有乙個...

bzoj 4337 樹的同構

傳送門 樹同構模板題。為了保險用了雙雜湊。選了極其暴力的方法處理兩個重心的情況 對於每個重心分別求雜湊值然後取max。雜湊的時候,每次將所有子節點的雜湊值排好序拿出來,然後看心情瞎搞,隨便乘一乘模一模,最後將根節點的雜湊值作為整棵樹的雜湊值。include include include inclu...

BJOI2017 樹的難題

按照常規思路,選乙個點x作為分治中心,拼接x出發到子樹各點的路徑。對於拼接時兩段介面處 即x連出的那條邊,若沒有,設為0號邊 顏色為0,長度為0,到達0號兒子 顏色的影響,可以記錄每段的路徑權值 邊數以及該段的介面,將所有的路徑以介面顏色為第一關鍵字,介面編號為第二關鍵字排序。顯然,對於同一介面的路...