树哈希判断同构无根同构问题转有根同构问题
生活随笔
收集整理的這篇文章主要介紹了
树哈希判断同构无根同构问题转有根同构问题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言
判斷無根的同構(gòu)
利用重心作為根進(jìn)行dfs處理
注意哈希的公式:
f[fa]=∑f[son]*primesiz[fa]
這個東西好像也是千變?nèi)f化
復(fù)雜度:nmlogn
代碼
#include<bits/stdc++.h> using namespace std; #define ll long long #define int long long const int N=3e5+100; const int mod=1019260817; const int key=131; int n,m; int x,y; struct node{int to,nxt; }p[N<<1]; int fi[N],cnt; ll mi[N]; void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt; } int siz[N],r,rr,res,dep[N]; void find_r(int x,int f){siz[x]=1;int mx=0;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;//printf("x=%d to=%d\n",x,to);if(to==f) continue;find_r(to,x);siz[x]+=siz[to];mx=max(mx,siz[to]);}mx=max(mx,n-siz[x]);//printf("x=%d f=%d siz=%d hson=%d mx=%d res=%d\n",x,f,siz[x],hson[x],mx,res);if(!r||mx<res){r=x;res=mx;rr=0;}else if(mx==res){rr=x;} } typedef pair<int,int>pr; #define mkp make_pair int has[N]; pr q[N]; int num; void dfs(int x,int f){dep[x]=dep[f]+1;has[x]=(ll)(dep[x]*key)%mod,siz[x]=1;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==f) continue;//dep[to]=dep[x]+1;dfs(to,x);}num=0;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==f) continue;q[++num]=mkp(has[to],siz[to]);siz[x]+=siz[to];}sort(q+1,q+1+num);for(int i=1;i<=num;i++){has[x]=(ll)(has[x]+(ll)q[i].first*mi[siz[x]])%mod;//siz[x]+=q[i].second;} // printf(" x=%d has=%d\n",x,has[x]); }int fa[N],fb[N]; void add(int tag){scanf("%d",&n);fill(fi,fi+1+n,-1);cnt=-1;for(int i=1;i<=n;i++){scanf("%d",&x);if(x) addline(i,x),addline(x,i);}r=rr=0;find_r(1,0); // printf("i=%d r=%d rr=%d\n",tag,r,rr); // printf("r=%d\n",r);dfs(r,0);fa[tag]=has[r];if(rr) {/*printf("r=%d\n",rr);*/dfs(rr,0);fb[tag]=has[rr];}if(rr&&fa[tag]>fb[tag]) swap(fa[tag],fb[tag]); // printf("i=%d fa=%d fb=%d\n",tag,fa[tag],fb[tag]); } signed main(){ // freopen("split.in","r",stdin); // freopen("split.out","w",stdout);mi[0]=1;for(int i=1;i<=50;i++) mi[i]=(ll)mi[i-1]*key%mod;scanf("%d",&m);for(int i=1;i<=m;i++) add(i);for(int i=1;i<=m;i++){for(int j=1;j<=m;j++){if(fa[i]==fa[j]&&fb[i]==fb[j]){printf("%d\n",j);break;}}}return 0; } /* 5 1 1 2 1 3 3 5 3 4 2 311 3 1 2 2 3 2 4 1 5 5 6 5 7 5 8 6 9 8 10 8 11 2 9 3 6 2 8 */總結(jié)
以上是生活随笔為你收集整理的树哈希判断同构无根同构问题转有根同构问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全国首例:使用麒麟底层平台的国产收费系统
- 下一篇: 8.16模拟:树上算法