私は特に問題の練習を書きました
まず、3例の合計は:1ルート2の息子、そして3つの他のノードを削除し、葉を削除します
、次数2の第2のノードなしに、次数4のノードが存在する第三のケース次数2つのノードが存在することになる第一ケース
そして、今からカイをドロップ..
まず、サイズも通常サイズ-1 0ダイレクト出力の通常のポイントどちらを満たした場合、通常より1少なくなりますルートサイズまで削除する観点から、各点の大きさについて尋ねます
ポイント数は、出力間違ったサイズ0でない場合
単一のユニークな決意と3オフライン2のようなもの
あなたはディスクセグメントの直径が0でないものを見つけることができます限り、この問題に対する解決策の公式
それは理にかなっています。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int M = 1000001;
int n,m,k,a[M],s[M],N,ver[M],nex[M],head[M],cnt,dp[M],vis[M],S2,S4,x,y,d[M];
queue<int>q,rs;
void add(int x,int y)
{
ver[++cnt]=y, nex[cnt]=head[x], head[x]=cnt;
ver[++cnt]=x, nex[cnt]=head[y], head[y]=cnt;
}
int main()
{
scanf("%d",&N); n=(1<<N)-1;
if(N==2)
{
printf("2\n1 2");
return 0;
}
for(int i=1;i<=n-2;i++)
{
scanf("%d%d",&x,&y);
d[x]++, d[y]++;
add(x,y);
}
for(int i=1;i<n;i++)
{
s[i]=1;
if(d[i]==2) S2++;
if(d[i]==4 && S4) { printf("0"); return 0; }
if(d[i]==4) S4=i;
if(d[i]>4) { printf("0"); return 0; }
}
if(S2==2 && S4) { printf("0"); return 0; }
for(int i=1;i<=n-1;i++) if(d[i]==1) s[i]=1,q.push(i);
while(q.size())
{
int x=q.front(); q.pop();
vis[x]=1;
for(int i=head[x];i;i=nex[i])
{
if(vis[ver[i]]) continue;
s[ver[i]]+=s[x]; d[ver[i]]--;
if(d[ver[i]]==1)q.push(ver[i]);
}
}
int x=0,S=0;
for(int i=1;i<n;i++)
{
int k=s[i]+2,g=s[i]+1;
if((g & -g) == g) continue;
if((k & -k) !=k) { printf("0"); return 0; }
if(!x || s[i]<s[x]) x=i;
S++;
}
if(!S2)
{
int B=0;
for(int i=1;i<n;i++) if(s[i]==(n-1)/2) B=i;
if(B)
{
printf("2\n");
printf("%d %d",min(x,B),max(x,B));
return 0;
}
}
int k=s[x]+2,t=-1;
while(k) k>>=1, t++;
if(S!=N-t+1) { printf("0"); return 0; }
if(x) {printf("1\n%d",x); return 0;}
printf("2\n");
for(int i=1;i<n;i++)
{
if(s[i]==(n-1)/2) printf("%d ",i);
}
}