題解:
樹的同構的判定
有根樹從根開始進行樹hash
先把兒子的f進行排序
$f[i]=\sum_^ +num[i]$(我沒有仔細想這樣是不是樹是唯一的。。。反正過了)
無根樹先找到重心再作為根
因為重心最多只有兩個,複雜度仍舊o(n)
**:
#include usingnamespace
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號兒子 顏色的影響,可以記錄每段的路徑權值 邊數以及該段的介面,將所有的路徑以介面顏色為第一關鍵字,介面編號為第二關鍵字排序。顯然,對於同一介面的路...