【CF1252F】Regular Forestation(重心,树同构)
题意:给定一棵n个点的树,问删去某个点之后所有的树同构,这样分割出来的树最多能有几棵
n<=4000
思路:分割成至少两个size相等的联通块之后size必定小于n/2,与树的重心的定义相同
预处理出重心(0,1或2个)之后上无根树同构板子
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,ll>P;
#define N 200010
#define M 1000000
#define INF 1e9
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1
#define fors(i) for(auto i:e[x]) if(i!=p) const int MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int dx[]={-,,,};
int dy[]={,,-,}; int head[N],vet[N],nxt[N],sz[N],mx[N],d[N],tot,Size,root; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} ll readll()
{
ll v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void add(int a,int b)
{
nxt[++tot]=head[a];
vet[tot]=b;
head[a]=tot;
} void dfs1(int u,int fa)
{
int e=head[u];
sz[u]=,mx[u]=;
while(e)
{
int v=vet[e];
if(v!=fa)
{
dfs1(v,u);
sz[u]+=sz[v];
mx[u]=max(mx[u],sz[v]);
}
e=nxt[e];
}
} int ra[N]; int pw(int x,int y)
{
int res=;
while(y)
{
if(y&) res=1ll*res*x%MOD;
x=1ll*x*x%MOD;
y>>=;
}
return res;
} int inv(int x)
{
return pw(x,MOD-);
} struct Sub
{
VI S;
int d1,d2,H1,H2;
Sub(){d1=d2=; S.clear();} void add(int d,int v)
{
S.pb(v);
if(d>d1) d2=d1,d1=d;
else if(d>d2) d2=d;
} int Hash()
{
H1=H2=;
for(int i:S)
{
H1=1ll*H1*(ra[d1]+i)%MOD;
H2=1ll*H2*(ra[d2]+i)%MOD;
}
return H1;
} PII del(int d,int v)
{
if(d==d1) return {d2+,1ll*H2*inv(ra[d2]+v)%MOD};
return {d1+,1ll*H1*inv(ra[d1]+v)%MOD};
}
}; PII U[N];
int n,i,x,y,A[N];
Sub T[N]; void prepare(int n)
{
rep(i,,n) ra[i]=rand()%MOD;
} void dfsD(int u,int p)
{
Size++;
T[u]=Sub();
int e=head[u];
while(e)
{
int v=vet[e];
if(v!=p)
{
dfsD(v,u);
T[u].add(T[v].d1+,T[v].H1);
}
e=nxt[e];
}
T[u].Hash();
} void dfsU(int u,int p)
{
if(p!=root) T[u].add(U[u].fi,U[u].se);
A[u]=T[u].Hash();
int e=head[u];
while(e)
{
int v=vet[e];
if(v!=p)
{
U[v]=T[u].del(T[v].d1+,T[v].H1);
dfsU(v,u);
}
e=nxt[e];
}
} int isok(int root,int block)
{
int t[],c[];
int s=;
int e=head[root];
while(e)
{
int v=vet[e];
rep(i,,n) A[i]=;
Size=;
dfsD(v,root);
dfsU(v,root);
if(Size!=block) return ;
s++;
if(s==)
{
sort(A+,A+n+);
rep(i,,n) c[i]=A[i];
}
else
{
sort(A+,A+n+);
rep(i,,n)
if(A[i]!=c[i]) return ;
}
e=nxt[e];
}
return ;
} int main()
{
VI r;
srand();
prepare();
n=read();
rep(i,,n) head[i]=d[i]=;
tot=;
rep(i,,n-)
{
int x=read(),y=read();
add(x,y);
add(y,x);
d[x]++; d[y]++;
}
dfs1(,); r.clear(); rep(i,,n)
if(d[i]>=&&max(mx[i],n-sz[i])<=n/) r.pb(i); int ans=;
for(int i=;i<r.size();i++)
{
root=r[i];
if(isok(r[i],mx[r[i]])) ans=max(ans,d[r[i]]);
}
if(ans==) printf("-1\n");
else printf("%d\n",ans);
return ;
}
【CF1252F】Regular Forestation(重心,树同构)的更多相关文章
- Regular Forestation CodeForces - 1252F(树同构)
Regular Forestation \[ Time Limit: 1000 ms\quad Memory Limit: 262144 kB \] 题意 给出一个节点为 \(n\) 的树,问删掉树上 ...
- uva12489 Combating cancer(树同构)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud https://uva.onlinejudge.org/index.php?opt ...
- Bzoj3197/洛谷3296 [SDOI2013]刺客信条assassin(树的重心+树Hash+树形DP+KM)
题面 Bzoj 洛谷 题解 (除了代码均摘自喻队的博客,可是他退役了) 首先固定一棵树,枚举另一棵树,显然另一棵树只有与这棵树同构才有可能产生贡献 如果固定的树以重心为根,那么另一棵树最多就只有重心为 ...
- BZOJ4337: BJOI2015 树的同构(hash 树同构)
题意 题目链接 Sol 树的同构问题,直接拿hash判一下,具体流程大概是这样的: 首先转化为有根树,预处理出第\(i\)棵树以\(j\)为根时的hash值. 那么两个树同构当且仅当把两棵树的hash ...
- Luogu 5043 【模板】树同构([BJOI2015]树的同构)
BZOJ 4337 简单记录一种树哈希的方法:以$x$为根的子树的哈希值为$\sum_{y \in son(x)}f_y*base_i$,$f_y$表示以$y$为根的树的哈希值,其中$i$表示$f_y ...
- 『Andrew and Chemistry 树同构』
Andrew and Chemistry Description During the chemistry lesson Andrew learned that the saturated hydro ...
- luogu P5043 【模板】树同构 hash 最小表示法
LINK:模板 树同构 题目说的很迷 给了一棵有根树 但是重新标号 言外之意还是一棵无根树 然后要求判断是否重构. 由于时无根的 所以一个比较显然的想法暴力枚举根. 然后做树hash或者树的最小表示法 ...
- 【BZOJ3162】独钓寒江雪 树同构+DP
[BZOJ3162]独钓寒江雪 题解:先进行树hash,方法是找重心,如果重心有两个,则新建一个虚点将两个重心连起来,新点即为新树的重心.将重心当做根进行hash,hash函数不能太简单,我的方法是: ...
- 【BZOJ3197】[Sdoi2013]assassin 树同构+动态规划+KM
[BZOJ3197][Sdoi2013]assassin Description Input Output Sample Input 4 1 2 2 3 3 4 0 0 1 1 1 0 0 0 Sam ...
随机推荐
- CNN(卷积神经网络)原理讲解及简单代码
一.原理讲解 1. 卷积神经网络的应用 分类(分类预测) 检索(检索出该物体的类别) 检测(检测出图像中的物体,并标注) 分割(将图像分割出来) 人脸识别 图像生成(生成不同状态的图像) 自动驾驶 等 ...
- [DS+Algo] 010 二叉树的遍历
二叉树遍历 深度优先 一般用递归 一些名词 遍历方式 英文 先序 Preorder 中序 Inorder 后序 Postorder 广度优先 一般用队列 Python 代码示例 class Node( ...
- 如何学习MySQL数据库管理员(OCP)认证(转)
如何学习MySQL数据库管理员(OCP)认证 转自: 甲骨文专家中,MySQL 5.6数据库管理员( OCP )证明您的安装和优化MySQL服务器,设置复制和安全,执行数据库备份及性能优化和保护M ...
- MySQL-快速入门(14)MySQL性能优化
1.MySQL性能优化包括查询速度优化.数据库结构优化.数据库服务器优化等. 优化的切入点:合理的结构设计.表结构.索引.查询语句. 2.show status查询数据库的性能参数 show stat ...
- Mybatis-学习笔记(4)1对1、1对多、多对多
1.1对1 有2种方式对内嵌Bean设值: 1>关联查询就一条语句.使用association关键字,直接将嵌套对象的映射表的字段赋值内嵌对象. <association property ...
- IDEA--错误:找不到或无法加载XXXXX--解决方法--创建javafx或其他项目出现的问题
今天一上午超厂长在学习javafx的时候,总是创建一个然后运行就会出现 出现错误:找不到或无法加载主类 找了二个小时,都说是jdk或者其他环境配置问题 按照那些改了也没用重新创建一个也提示出现错误:找 ...
- 2018 Web 开发者路线图[转载]
2018 Web 开发者路线图[转载] https://qianduan.group/posts/5a66f36e0cf6b624d2239c74?hmsr=toutiao.io&utm_me ...
- Codeforces1234F. Yet Another Substring Reverse(状压dp)
题目链接:传送门 思路: 由于只能翻转一次子串,就相当于找出两个不连续的子串,把在后面的一个子串翻转过来,和第一个子串拼接. 因为题目仅要求子串中的字符不重复,所以字符的先后顺序无关,翻转的操作就相当 ...
- 可持久化+Trie || BZOJ 3261最大异或和 || Luogu P4735 最大异或和
题面:最大异或和 代码: #include<cstdio> #include<cstring> #include<iostream> using namespace ...
- Python核心技术与实战——六|异常处理
和其他语言一样,Python中的异常处理是很重要的机制和代码规范. 一.错误与异常 通常来说程序中的错误分为两种,一种是语法错误,另一种是异常.首先要了解错误和异常的区别和联系. 语法错误比较容易理解 ...