专栏文章
题解:P13642 EERT
P13642题解参与者 2已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @miogzqfu
- 此快照首次捕获于
- 2025/12/02 19:03 3 个月前
- 此快照最后确认于
- 2025/12/02 19:03 3 个月前
思路
#0
枚举全排列,检验合法性。
#2
菊花图。
可以发现,不管怎么走,都无法走到根节点,所以无解。
#3
链。
对于所有深度为奇数的点,两点间必定没有连边,可以直接走。
偶数位同理。
所以可以先走偶数位,再走奇数位。
特判 时无解即可。
#5
设最大深度为 。
对于 时,有以下解法。
对于同一深度的点,两两间必定没有连边,可以直接走。
把同一深度的点看成一个点,做法同链。
当 时,树为菊花,无解。
当 时,显然只能先走根,再走第三层,最后走第二层。
只要保证第二层最先走到点不为第三层最后一个点的父亲即可。
所以必须满足第二层点数不为 。
代码
CPP#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define p_q priority_queue
#define pb push_back
#define mk make_pair
#define pii pair<int,int>
#define ve vector
#define endl '\n'
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define lowbit(x) (x&(-x))
int dep[10000005],mx,cnt[10000005],cnt1[10000005],a[10000005],fa[105][105];
int k[10000005],vis[25],an[25],m,ans_[25],is_ans;
ve<int>ans;
void dfs(int x){
if(is_ans) return ;
if(x==m+1){
is_ans=1;
for(int i=1;i<=m;i++){
ans_[i]=an[i];
}
return ;
}
if(x==1){
for(int i=1;i<=m;i++){
vis[i]=1;
an[x]=i;
dfs(x+1);
vis[i]=0;
}
}else{
for(int i=1;i<=m;i++){
if(!fa[an[x-1]][i]&&!vis[i]){
vis[i]=1;
an[x]=i;
dfs(x+1);
vis[i]=0;
}
}
}
}
std::vector<int> eert(int N,std::vector<int> f){
for(int i=2;i<=N;i++){
dep[i]=dep[f[i-2]]+1;
cnt[dep[i]]++;
mx=max(mx,dep[i]);
}
if(N<=10){//直接暴力
m=N;
for(int i=2;i<=m;i++){
fa[i][f[i-2]]=1;
fa[f[i-2]][i]=1;
}
dfs(1);
if(!is_ans) return ans;
for(int i=1;i<=m;i++) ans.pb(ans_[i]);
return ans;
}
if(mx==1){
return ans;
}
if(mx<=2){
for(int i=1;i<mx;i++){
if(cnt[i]==1){
return ans;
}
}
for(int i=1;i<=mx;i++){
k[i]=0;
cnt1[i]=cnt[i];
cnt[i]+=cnt[i-1];
}ans.pb(1);
for(int i=2;i<=N;i++){
a[cnt[dep[i]-1]+cnt1[dep[i]]]=i;
cnt1[dep[i]]--;
}
if(cnt[2]==1){
int _;
for(int j=cnt[2-1]+1;j<=cnt[2];j++){
ans.pb(a[j]);
_=a[j];
}
for(int j=cnt[1-1]+1;j<=cnt[1];j++){
if(a[j]!=f[_-2]) ans.pb(a[j]);
}
ans.pb(f[_-2]);
return ans;
}
for(int i=2;i<=mx;i++){
for(int j=cnt[i-1]+1;j<=cnt[i];j++){
if(f[a[j]-2]!=a[cnt[i-2]+1]){
k[i]=a[j];
break;
}
}
}
for(int i=mx;i>=1;i--){
for(int j=cnt[i-1]+1;j<=cnt[i];j++){
if(a[j]!=k[i]) ans.pb(a[j]);
}
if(k[i]) ans.pb(k[i]);
}
return ans;
}
else{
for(int i=1;i<=mx;i++){
cnt1[i]=cnt[i];
cnt[i]+=cnt[i-1];
}
for(int i=2;i<=N;i++){
a[cnt[dep[i]-1]+cnt1[dep[i]]]=i;
cnt1[dep[i]]--;
}
for(int i=1;i<=mx;i+=2){
for(int j=cnt[i-1]+1;j<=cnt[i];j++){
if(a[j]!=k[i]) ans.pb(a[j]);
}
}
ans.pb(1);
for(int i=2;i<=mx;i+=2){
for(int j=cnt[i-1]+1;j<=cnt[i];j++){
ans.pb(a[j]);
}
}
return ans;
}
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...