HDU 5732 Subway
2016-07-23 17:12
381 查看
给定两棵同构的树,要求输出对应的点对。
Hash
以及造数据的程序 :{
启发式合并+树的最小表示法
Hash
#include<algorithm> #include<iostream> #include<cstring> #include<cassert> #include<cstdio> #include<bitset> #include<queue> #include<cmath> #include<ctime> #include<map> #define inf (1<<30) #define INF (1ll<<62) #define fi first #define se second #define prt(x) cout<<#x<<":"<<x<<" " #define prtn(x) cout<<#x<<":"<<x<<endl using namespace std; typedef long long ll; typedef pair<int,int> ii; template<class T>void sc(T &x){ int f=1;x=0;char c; while(c=getchar(),c<48)if(c=='-')f=-1; do x=x*10+(c^48); while(c=getchar(),c>47); x*=f; } template<class T>void nt(T x){ if(!x)return; nt(x/10);putchar('0'+x%10); } template<class T>void pt(T x){ if(x<0)putchar('-'),x=-x; if(!x)putchar('0'); else nt(x); } int n; const int maxn=100005; int last[2][maxn],ecnt; struct Edge{ int to,nxt; Edge(){} Edge(int a,int b):to(a),nxt(b){} }e[maxn<<2]; void ins(int *last,int u,int v){ e[ecnt]=Edge(v,last[u]); last[u]=ecnt++; } struct abcd{ vector<string>a; map<string,int>b; void init(){ a.clear(); b.clear(); } int operator [] (string c){ if(b.find(c)!=b.end())return b[c]; a.push_back(c); return b[c]=a.size();; } string operator [] (int c){ return a[c-1]; } }name; ii RT; int sz[maxn]; void dfs(int *last,int x,int f){ sz[x]=1; bool ok=true; for(int i=last[x];i!=-1;i=e[i].nxt){ int to=e[i].to; if(to==f)continue; dfs(last,to,x); ok&=sz[to]<=n/2; sz[x]+=sz[to]; }ok&=(n-sz[x])<=n/2; if(!ok)return; if(RT.fi==-1)RT.fi=x; else RT.se=x; } void find_rt(int *last){ RT.fi=RT.se=-1; dfs(last,1,0); } int has[2][maxn];//val,id int H[maxn]; int link[maxn]; const int Pa=674679;//4679 const int Pb=165537;//65537 const int Pp=435617;//35617 const int Pq=1000000033; void gethash(int *has,int *last,int x,int f){ for(int i=last[x];i!=-1;i=e[i].nxt){ int to=e[i].to; if(to!=f)gethash(has,last,to,x); } int tot=0; for(int i=last[x];i!=-1;i=e[i].nxt){ int to=e[i].to; if(to!=f)H[++tot]=has[to]; } sort(H+1,H+tot+1); ll res=Pa; for(int i=1;i<=tot;i++) res=(res*Pp^H[i])%Pq; res=res*Pb%Pq; has[x]=res; } ii HA[maxn],HB[maxn]; bool chk(int x,int fx,int y,int fy){ int na,nb;na=nb=0; for(int i=last[0][x];i!=-1;i=e[i].nxt){ int to=e[i].to; if(to==fx)continue; HA[++na]=ii(has[0][to],to); } for(int i=last[1][y];i!=-1;i=e[i].nxt){ int to=e[i].to; if(to==fy)continue; HB[++nb]=ii(has[1][to],to); } if(na!=nb)return false; sort(HA+1,HA+na+1); sort(HB+1,HB+nb+1); for(int i=1;i<=na;i++){ if(HA[i].fi!=HB[i].fi)return false; link[HA[i].se]=HB[i].se; } for(int i=last[0][x];i!=-1;i=e[i].nxt){ int to=e[i].to; if(to==fx)continue; if(!chk(to,x,link[to],y))return false; } return true; } bool match(int x,int y){ gethash(has[0],last[0],x,0); gethash(has[1],last[1],y,0); if(has[0][x]!=has[1][y])return false; link[x]=y; return chk(x,0,y,0); } void output(){ for(int i=1;i<=n;i++) cout<<name[i]<<" "<<name[link[i]]<<endl; } void solve(){ string u,v; name.init(); ecnt=0; for(int i=0;i<2;i++){ memset(last[i],-1,n+1<<2); for(int a,b,j=1;j<n;j++){ cin>>u>>v; a=name[u]; b=name[v]; ins(last[i],a,b); ins(last[i],b,a); } } ii rt[2]; for(int i=0;i<2;i++){ find_rt(last[i]); rt[i]=RT; } // for(int i=0;i<2;i++) // prt(rt[i].fi),prtn(rt[i].se); if(match(rt[0].fi,rt[1].fi))output(); else if(match(rt[0].fi,rt[1].se))output(); else puts(":{"); } int main(){ // freopen("pro.in","r",stdin); // freopen("chk.out","w",stdout); while(~scanf("%d",&n))solve();//*INF return 0; }
以及造数据的程序 :{
#include<algorithm> #include<iostream> #include<cstring> #include<cassert> #include<cstdio> #include<bitset> #include<queue> #include<cmath> #include<ctime> #define inf (1<<30) #define INF (1ll<<62) #define prt(x) cout<<#x<<":"<<x<<" " #define prtn(x) cout<<#x<<":"<<x<<endl using namespace std; typedef long long ll; template<class T>void sc(T &x){ int f=1;x=0;char c; while(c=getchar(),c<48)if(c=='-')f=-1; do x=x*10+(c^48); while(c=getchar(),c>47); x*=f; } template<class T>void nt(T x){ if(!x)return; nt(x/10);putchar('0'+x%10); } template<class T>void pt(T x){ if(x<0)putchar('-'),x=-x; if(!x)putchar('0'); else nt(x); } const int n=100000; struct Edge{ int u,v; }edge[n+5]; int f[n+5]; int Rand(){ return rand()<<15|rand(); } int main(){ srand(time(0)); freopen("pro.in","w",stdout); printf("%d\n",n); for(int i=2;i<=n;i++) edge[i]=(Edge){Rand()%(i-1)+1,i}; for(int i=2;i<=n;i++) printf("%d %d\n",edge[i].u,edge[i].v); for(int i=1;i<=n;i++) f[i]=i,swap(f[i],f[Rand()%i+1]); for(int i=1;i<=100000;i++){ int u=Rand()%n+1,v=Rand()%n+1; if(u!=1&&v!=1)swap(edge[u],edge[v]); } for(int i=2;i<=n;i++){ printf("%d %d\n",f[edge[i].u],f[edge[i].v]); } return 0; }
启发式合并+树的最小表示法
相关文章推荐
- 奶牛的锻炼-线性dp
- 个人android开发风险得与失
- Linux终端常用快捷键
- php项目笔记(二)php部分
- C#基础之枚举
- mongodb update
- OOC 面向对象C语言编程实践
- 重学搜索yi.2:Lake Counting--dfs
- 浅谈OOP与AOP关系
- 我刚刚写了一个map的题目,还用到了#include<string>的头文件,下面我来总结一下 map<类型>变量 q q.find(找字符串) q.end()是否到达末尾
- SSH服务器拒绝了密码,xshell连不上虚拟机怎么办
- 一道阿里校春招笔试题
- Android手机耗电分析
- 013-句子逆序
- 智勇三国 单机小游戏
- iOS开发中的 并发编程锁
- HDU 1026 Ignatius and the Princess I【BFS+优先队列+栈路径输出】
- linux 內核用戶指導:內核配置、編譯,安裝(內核鏡像、設備樹Binaries、模組)
- 在屏幕中显示复选框
- Codeforces 701C They Are Everywhere(尺取/双指针)