• Jzoj1155 有根树的同构(树的Rabin-Karp)


    这里简单说一下rabin-karp

    其实就是字符串hash算法,不理解的可以自行百度

    对于一颗树,我们可以将其变为一个括号序列,对这个括号序列作rabin-karp,让后就可以轻松判断同构了是不是很简单

    细节不多说,有一点必须注意:因为子树是无序的,所以dfs时必须对子树排序

    #include<stdio.h>
    #include<string.h>
    #include<vector>
    #include<algorithm>
    using namespace std;
    #define SL __int128
    #define BASE 313
    SL pow(SL x,int k){
    	SL S=1;
    	for(;k;x*=x,k>>=1) if(k&1) S*=x;
    	return S;
    }
    struct HASH{ 
    	int l; SL v;
    	//HASH(){ l=v=0; }
    };
    bool operator < (HASH a,HASH b){ return a.v<b.v; }
    HASH operator + (HASH a,HASH b){
    	return (HASH){a.l+b.l,a.v*pow(BASE,b.l)+b.v};
    }
    int cnt,h[1000],v[1000],nt[1000],f[1000],n,m;
    SL H[1000]; 
    void adj(int x,int y){
    	v[++cnt]=y; nt[cnt]=h[x]; h[x]=cnt;
    }
    vector<HASH> ch[1000];
    HASH dfs(int x){
    	HASH ans={0,0}; ch[x].clear();
    	for(int i=h[x];i;i=nt[i])
    		ch[x].push_back(dfs(v[i]));
    	sort(ch[x].begin(),ch[x].end()); //这里非常重要!
    	for(int i=0,z=ch[x].size();i<z;++i) ans=ans+ch[x][i];
    	ans=(HASH){1,'('}+ans+(HASH){1,')'};
    	return ans;
    }
    int main(){
    	scanf("%d%d",&m,&n);
    	for(int k=1;k<=m;++k){
    		cnt=0; 
    		memset(f,0,sizeof f);
    		memset(h,0,sizeof h);
    		for(int x,y,i=1;i<n;++i){
    			scanf("%d%d",&x,&y);
    			adj(x,y); f[y]=x;
    		}
    		for(int i=1;i<=n;++i) 
    			if(!f[i]) H[k]=dfs(i).v;
    	}
    	bool vis[1010]={0};
    	for(int i=1;i<=m;++i)
    		if(!vis[i]){
    			vis[i]=1|printf("%d",i);
    			for(int j=i+1;j<=m;++j)
    				if(H[i]==H[j]) vis[j]=1|printf("=%d",j);
    			puts("");
    		}
    	return 0;
    }


  • 相关阅读:
    大端序与小端序
    中断分类
    PHP开发框架[国内框架]
    PHP开发框架[流行度排名]
    ecshop 后台分页功能
    Windows下phpStudy中的Apache无法启动的排查方法
    Windows里配置Apache2.2+PHP5.3+mod_fcgid运行高效的FastCGI模式
    Apache多虚拟主机多版本PHP(5.2+5.3+5.4)共存运行配置全过程
    让 Node.js 支持 ES6 的语法
    微信小程序请求wx.request数据,渲染到页面
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477372.html
Copyright © 2020-2023  润新知