bzoj4474: [Jsoi2015]isomorphism
树hash啊
我的做法很垃圾,就是yy一种只有一个孩子时hash值和孩子一样的hash法
然后用重心去作为根遍历
这样有点问题,就是重心假如也是要删掉的那就gg了
那我们求tot的时候删掉的点就不管直接设为0,求重心的时候也不管这些删掉的点就可以了
其实
先把新的树建出来不好吗
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const int _=1e2; const int maxn=1e4+_; const int maxt=20+3; const LL hbase=233; LL mi[maxn]; void hyu(){mi[0]=1;for(int i=1;i<maxn;i++)mi[i]=mi[i-1]*hbase;} struct TREE { int id,ptt; TREE(){ptt=0;} struct node { int x,y,next; }a[2*maxn];int len,last[maxn],du[maxn]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; du[x]++; if(du[x]==2)ptt++; else if(du[x]==3)ptt--; } //---------------------------------def-------------------------------------------- int tot[maxn]; void dfs(int x,int fr) { if(du[x]==2)tot[x]=0; else tot[x]=1; for(int k=last[x];k;k=a[k].next) if(a[k].y!=fr)dfs(a[k].y,x),tot[x]+=tot[a[k].y]; } int G[maxn]; void getrt(int x,int fr) { G[x]=0; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; G[x]=max(G[x],tot[y]); if(y!=fr) { tot[x]-=tot[y]; tot[y]+=tot[x]; getrt(y,x); tot[y]-=tot[x]; tot[x]+=tot[y]; } } } //----------------------------------getrt-------------------------------------------- int num;LL THash[2]; LL h[maxn]; int tlen; LL tt[maxn]; void gethash(int x,int fr) { for(int k=last[x];k;k=a[k].next) if(a[k].y!=fr)gethash(a[k].y,x); tlen=0; for(int k=last[x];k;k=a[k].next) if(a[k].y!=fr)tt[++tlen]=h[a[k].y]; if(tlen==0)h[x]=1; else { sort(tt+1,tt+tlen+1); h[x]=(tlen-1)*31; for(int i=1;i<=tlen;i++)h[x]+=tt[i]*mi[i-1]; } } //---------------------------------gethash------------------------------------------- void main() { int n,x,y; scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); ins(x,y),ins(y,x); } ptt=n-ptt; dfs(1,0),getrt(1,0); num=0; int mn=(1<<30); for(int i=1;i<=n;i++) if(du[i]!=2)mn=min(mn,G[i]); for(int i=1;i<=n;i++) if(mn==G[i]) gethash(i,0),THash[num++]=h[i]; } }tr[maxt]; bool check(int x,int y) { for(int i=0;i<tr[x].num;i++) for(int j=0;j<tr[y].num;j++) if(tr[x].THash[i]==tr[y].THash[j])return true; return false; } int aslen,as[maxt]; bool cmp(int x,int y){return tr[x].ptt<tr[y].ptt;} int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int m; scanf("%d",&m);hyu(); for(int i=1;i<=m;i++) tr[i].id=i,tr[i].main(); for(int i=1;i<=m;i++) { bool bk=false; for(int j=1;j<=aslen;j++) if(check(i,as[j])){bk=true;break;} if(!bk)as[++aslen]=i; } sort(as+1,as+aslen+1,cmp); printf("%d\n",aslen); for(int i=1;i<aslen;i++)printf("%d ",tr[as[i]].ptt); printf("%d\n",tr[as[aslen]].ptt); return 0; }
pain and happy in the cruel world.