bzoj 4474: [Jsoi2015]isomorphism
来源:互联网 发布:笑郭网络验证教程 编辑:程序博客网 时间:2024/05/01 12:51
Description
一个无向树的度数为 2的结点称为假结点,其它结点称为真结点。一个无向树的简化树
其结点由原树的全体真结点组成,两个真结点之间有边当且仅当它们在原树中有边,或者在
原树中有一条联结这两个结点的路,其中间节点全是假结点。两个无向树各自的简化树如果
同构,即存在结点之间的一一对应,使得在一个树中的任意两个结点之间有边当且仅当它们
的对应结点在另一个树中有边,则称原来的两个无向树实质同构。给定若干个无向树,将相
互实质同构的无向树只保留一个其余删除。统计剩下的相互不实质同构的无向树个数,并将
它们的简化树结点个数从小到大输出。
Input
第一行只有一个正整数 m,后面依次输入m个无向树,每个无向树先用一行输入结点个
数n,结点就用1到n表示,然后用n-1行输入n-1条无向边,每行有两个 1到n 之间的不
同的正整数,用一个空格隔开,代表这两个结点之间有无向边。两个树之间无空行。
2<=m<=20, 2<=n<=10000
Output
第一行输出一个正整数,即输入中不计实质同构包含无向树的个数 m0(1<=m0<=m)。第
二行包含不严格递增的 m0个正整数,表示这m0个无向树的简化树结点个数。相邻两数用一
个空格隔开。
Sample Input
2
4
1 4
2 4
3 4
5
1 3
2 3
3 4
4 5
4
1 4
2 4
3 4
5
1 3
2 3
3 4
4 5
Sample Output
1
4
4
似乎有一种可以判断树的同构的算法。不过我并不会。
写了个近似树hash的东西。记录了各种东西。
不知道有没有反例。。因为原题的数据比较弱。似乎只要随便多记录几种值比较就可以过了
#include<queue>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;struct line{ int s,t; int next;}a[202001];int head[101001];int edge;inline void add(int s,int t){ a[edge].next=head[s]; head[s]=edge; a[edge].s=s; a[edge].t=t;}int dge[10001],dgee[10001];int sux[21][10001],sumx[21][10001];int anx[21][10001],ansx[21][10001];int s[10001],sx[10001];int ss[10001],tt[10001];bool v[10001];inline bool cmp(int x,int y){ if(x>y) return true; return false;}inline int dfs(int d){ v[d]=true; if(dge[d]!=0) return dge[d]; int ans=0; int i; for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(!v[t]) ans+=dfs(t); } return ans;}int main(){ // freopen("isomorphism.in","r",stdin); // freopen("isomorphism.out","w",stdout); int n,m; scanf("%d",&n); int i,j; for(i=1;i<=n;i++) { scanf("%d",&m); memset(dge,0,sizeof(dge)); memset(dgee,0,sizeof(dgee)); edge=0; memset(head,0,sizeof(head)); memset(a,0,sizeof(a)); for(j=1;j<=m-1;j++) { scanf("%d%d",&ss[j],&tt[j]); edge++; add(ss[j],tt[j]); edge++; add(tt[j],ss[j]); dge[ss[j]]++; dge[tt[j]]++; } for(j=1;j<=m;j++) if(dge[j]==2) dge[j]=0; for(j=1;j<=m-1;j++) { memset(v,false,sizeof(v)); v[ss[j]]=true; dgee[dge[ss[j]]]+=dfs(tt[j]); memset(v,false,sizeof(v)); v[tt[j]]=true; dgee[dge[tt[j]]]+=dfs(ss[j]); } for(j=1;j<=m;j++) sumx[i][j]=dgee[j]; sort(dge+1,dge+1+m,cmp); for(j=1;j<=m;j++) { if(dge[j]==0) break; sux[i][j]=dge[j]; s[i]++; } } int k; int p=0; for(i=1;i<=n;i++) { bool flag=true; for(j=1;j<=p;j++) { if(s[i]!=sx[j]) continue; bool fx=true; for(k=1;k<=10000;k++) { if(sux[i][k]!=anx[j][k]||sumx[i][k]!=ansx[j][k]) { fx=false; break; } } if(fx) { flag=false; break; } } if(flag) { p++; for(j=1;j<=10000;j++) { anx[p][j]=sux[i][j]; ansx[p][j]=sumx[i][j]; } sx[p]=s[i]; } } printf("%d\n",p); sort(sx+1,sx+1+p); printf("%d",sx[1]); for(i=2;i<=p;i++) printf(" %d",sx[i]); printf("\n"); return 0;}
0 0
- bzoj 4474: [Jsoi2015]isomorphism
- 4474: [Jsoi2015]isomorphism
- BZOJ 1478 Sgu282 Isomorphism
- BZOJ 1478 Sgu282 Isomorphism 置换
- bzoj 4472: [Jsoi2015]salesman
- bzoj 4488: [Jsoi2015]最大公约数
- BZOJ 4481 [Jsoi2015] 非诚勿扰
- bzoj 4481 [Jsoi2015]非诚勿扰
- bzoj 4488: [Jsoi2015]最大公约数
- bzoj 4475: [Jsoi2015]子集选取
- bzoj 4477: [Jsoi2015]字符串树
- BZOJ 4475: [Jsoi2015]子集选取
- bzoj 4487 [Jsoi2015]染色问题
- BZOJ 4487 [Jsoi2015] 染色问题
- BZOJ 4484 [Jsoi2015] 最小表示
- bzoj 4484 [Jsoi2015]最小表示
- bzoj 4484: [Jsoi2015]最小表示
- bzoj 4477: [Jsoi2015]字符串树
- css3中伪类选择器:target的使用
- ibatis 到 MyBatis区别
- 框架整合学习笔记
- udp下接收发送数据
- 实践--升级数据库最佳写法
- bzoj 4474: [Jsoi2015]isomorphism
- threadid=11: thread exiting with uncaught exception (group=0x41898c38)
- java 环境变量的配置
- Mysql常用查询语句
- 剑指offer面试题之和为S的连续正数序列
- java学习之Java注解
- JS总结
- if_indextoname(unsigned ifindex, char *ifname)
- 第八届河南省程序设计大赛-NYOJ-1236-挑战密室