Codeforces 1228
D
直接暴力即可
——Qiyang
E
组合计数dp。
\(dp[i][j]=\sum_{l=0}^{j-1} dp[i-1][l]*k^l*C_{n-l}^{j-l}*(k-1)^{n-l}\)
组合计数水题。
考虑容斥可以做到\(O\left(n^2\right)\)
化一下那个柿子可以做到\(O\left(n\log n\right)\)
——Qiyang
F
大力分类讨论。
有一个显然的事情就是根一定是中心。
然后\(\texttt{check}\)一下就做完了。
注意一下分类的时候一定要仔细有很多叉点。
——Qiyang
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=140003;
int N,n,deg[maxn],b[5],sz[maxn],depth;
vector<int> g[maxn];
void ensure(bool cond){if(!cond){printf("0\n");exit(0);}}
void add(int u,int v){
ensure(u>=1&&u<=n+1&&v>=1&&v<=n+1);
g[u].push_back(v);
g[v].push_back(u);
}
void del(int u,int v){
ensure(u>=1&&u<=n+1&&v>=1&&v<=n+1);
g[u].erase(find(g[u].begin(),g[u].end(),v));
g[v].erase(find(g[v].begin(),g[v].end(),u));
}
int dfs1(int u,int last,int rt){
if(u==rt)return -1;
int mx=0,mxi=0;
sz[u]=1;
for(int v:g[u]){
if(v==last)continue;
if(dfs1(v,u,rt)==-1){
if(last)return -1;
else {sz[v]=-1;continue;}
}
sz[u]+=sz[v];
if(sz[v]>mx)mx=sz[v],mxi=v;
}
return mxi;
}
int dfs(int u,int last){
sz[u]=1;
for(int v:g[u]){
if(v==last)continue;
int tmp=dfs(v,u);
if(tmp){sz[u]=-1;return tmp;}
sz[u]+=sz[v];
}
return sz[u]==(n>>1)?u:0;
}
bool DFS(int u,int last,int dep){
if(g[u].size()==1&&last){
//printf("leaf\n");
if(!depth)depth=dep;
else if(depth!=dep)return 0;
return 1;
}
//for(int v:g[u])if(v!=last)printf("%d ",v);puts("");
if(!((last==0&&g[u].size()==2)||(last&&g[u].size()==3)))return 0;
for(int v:g[u]){
if(v==last)continue;
if(!DFS(v,u,dep+1))return 0;
}
return 1;
}
bool check(int u){
//printf("check root:%d\n",u);
depth=0;
return DFS(u,0,1);
}
int main(){
scanf("%d",&N);
n=(1<<N)-2;
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
deg[u]++,deg[v]++;
}
if(n==2){
printf("2\n1 2");
return 0;
}
for(int i=1;i<=n;i++)b[deg[i]]++;
if(b[2]==2&&b[4]==0){
int u1=0,u2=0;
for(u1=1;u1<=n&°[u1]!=2;u1++);
for(u2=u1+1;u2<=n&°[u2]!=2;u2++);
bool flag=0;
for(int v:g[u1])if(deg[v]==1){flag=1;break;}
if(flag)swap(u1,u2);
add(u2,n+1);
ensure(check(u1));
printf("1\n%d",u2);
}
else if(b[2]==1&&b[4]==1){
int u1=0,u2=0,v1=0,v2=0;
for(u1=1;u1<=n&°[u1]!=2;u1++);
for(u2=1;u2<=n&°[u2]!=4;u2++);
int v3=dfs1(u2,0,u1);
for(int v:g[u2])if(sz[v]!=-1&&v!=v3)v1==0?(v1=v):(v2=v);
del(u2,v1);
del(u2,v2);
add(u2,n+1);
add(n+1,v1);
add(n+1,v2);
ensure(check(u1));
printf("1\n%d",u2);
}
else if(b[2]==0&&b[4]==0){
int u1=0,u2=0,v1=0,v2=0;
for(v1=1;v1<=n&°[v1]!=1;v1++);
u1=dfs(v1,0);
for(int v:g[u1])if(sz[v]==-1){u2=v;break;}
v1=0;
for(int v:g[u1])if(v!=u2)v1==0?(v1=v):(v2=v);
del(u1,v1);
del(u1,v2);
add(u1,n+1);
add(n+1,v1);
add(n+1,v2);
ensure(check(u1));
printf("2\n%d %d",min(u1,u2),max(u1,u2));
}
else ensure(0);
return 0;
}