题意:给定一棵n个点的树,问删去某个点之后所有的树同构,这样分割出来的树最多能有几棵
n<=4000
思路:分割成至少两个size相等的联通块之后size必定小于n/2,与树的重心的定义相同
预处理出重心(0,1或2个)之后上无根树同构板子
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,ll> Pll; 9 typedef vector<int> VI; 10 typedef vector<PII> VII; 11 typedef pair<ll,ll>P; 12 #define N 200010 13 #define M 1000000 14 #define INF 1e9 15 #define fi first 16 #define se second 17 #define MP make_pair 18 #define pb push_back 19 #define pi acos(-1) 20 #define mem(a,b) memset(a,b,sizeof(a)) 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 23 #define lowbit(x) x&(-x) 24 #define Rand (rand()*(1<<16)+rand()) 25 #define id(x) ((x)<=B?(x):m-n/(x)+1) 26 #define ls p<<1 27 #define rs p<<1|1 28 #define fors(i) for(auto i:e[x]) if(i!=p) 29 30 const int MOD=1e9+7,inv2=(MOD+1)/2; 31 double eps=1e-6; 32 int dx[4]={-1,1,0,0}; 33 int dy[4]={0,0,-1,1}; 34 35 int head[N],vet[N],nxt[N],sz[N],mx[N],d[N],tot,Size,root; 36 37 int read() 38 { 39 int v=0,f=1; 40 char c=getchar(); 41 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 42 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 43 return v*f; 44 } 45 46 ll readll() 47 { 48 ll v=0,f=1; 49 char c=getchar(); 50 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 51 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 52 return v*f; 53 } 54 55 void add(int a,int b) 56 { 57 nxt[++tot]=head[a]; 58 vet[tot]=b; 59 head[a]=tot; 60 } 61 62 void dfs1(int u,int fa) 63 { 64 int e=head[u]; 65 sz[u]=1,mx[u]=0; 66 while(e) 67 { 68 int v=vet[e]; 69 if(v!=fa) 70 { 71 dfs1(v,u); 72 sz[u]+=sz[v]; 73 mx[u]=max(mx[u],sz[v]); 74 } 75 e=nxt[e]; 76 } 77 } 78 79 int ra[N]; 80 81 int pw(int x,int y) 82 { 83 int res=1; 84 while(y) 85 { 86 if(y&1) res=1ll*res*x%MOD; 87 x=1ll*x*x%MOD; 88 y>>=1; 89 } 90 return res; 91 } 92 93 int inv(int x) 94 { 95 return pw(x,MOD-2); 96 } 97 98 struct Sub 99 { 100 VI S; 101 int d1,d2,H1,H2; 102 Sub(){d1=d2=0; S.clear();} 103 104 void add(int d,int v) 105 { 106 S.pb(v); 107 if(d>d1) d2=d1,d1=d; 108 else if(d>d2) d2=d; 109 } 110 111 int Hash() 112 { 113 H1=H2=1; 114 for(int i:S) 115 { 116 H1=1ll*H1*(ra[d1]+i)%MOD; 117 H2=1ll*H2*(ra[d2]+i)%MOD; 118 } 119 return H1; 120 } 121 122 PII del(int d,int v) 123 { 124 if(d==d1) return {d2+1,1ll*H2*inv(ra[d2]+v)%MOD}; 125 return {d1+1,1ll*H1*inv(ra[d1]+v)%MOD}; 126 } 127 }; 128 129 PII U[N]; 130 int n,i,x,y,A[N]; 131 Sub T[N]; 132 133 void prepare(int n) 134 { 135 rep(i,0,n) ra[i]=rand()%MOD; 136 } 137 138 void dfsD(int u,int p) 139 { 140 Size++; 141 T[u]=Sub(); 142 int e=head[u]; 143 while(e) 144 { 145 int v=vet[e]; 146 if(v!=p) 147 { 148 dfsD(v,u); 149 T[u].add(T[v].d1+1,T[v].H1); 150 } 151 e=nxt[e]; 152 } 153 T[u].Hash(); 154 } 155 156 void dfsU(int u,int p) 157 { 158 if(p!=root) T[u].add(U[u].fi,U[u].se); 159 A[u]=T[u].Hash(); 160 int e=head[u]; 161 while(e) 162 { 163 int v=vet[e]; 164 if(v!=p) 165 { 166 U[v]=T[u].del(T[v].d1+1,T[v].H1); 167 dfsU(v,u); 168 } 169 e=nxt[e]; 170 } 171 } 172 173 int isok(int root,int block) 174 { 175 int t[5000],c[5000]; 176 int s=0; 177 int e=head[root]; 178 while(e) 179 { 180 int v=vet[e]; 181 rep(i,1,n) A[i]=0; 182 Size=0; 183 dfsD(v,root); 184 dfsU(v,root); 185 if(Size!=block) return 0; 186 s++; 187 if(s==1) 188 { 189 sort(A+1,A+n+1); 190 rep(i,1,n) c[i]=A[i]; 191 } 192 else 193 { 194 sort(A+1,A+n+1); 195 rep(i,1,n) 196 if(A[i]!=c[i]) return 0; 197 } 198 e=nxt[e]; 199 } 200 return 1; 201 } 202 203 int main() 204 { 205 VI r; 206 srand(23333); 207 prepare(5000); 208 n=read(); 209 rep(i,1,n) head[i]=d[i]=0; 210 tot=0; 211 rep(i,1,n-1) 212 { 213 int x=read(),y=read(); 214 add(x,y); 215 add(y,x); 216 d[x]++; d[y]++; 217 } 218 dfs1(1,0); 219 220 r.clear(); 221 222 rep(i,1,n) 223 if(d[i]>=2&&max(mx[i],n-sz[i])<=n/2) r.pb(i); 224 225 226 int ans=0; 227 for(int i=0;i<r.size();i++) 228 { 229 root=r[i]; 230 if(isok(r[i],mx[r[i]])) ans=max(ans,d[r[i]]); 231 } 232 if(ans==0) printf("-1 "); 233 else printf("%d ",ans); 234 return 0; 235 }