【CF1247F】Tree Factory(构造)

题意:给定一棵n个点的树,要求将一条可以随意标号的链通过若干次操作变成这棵树

一次操作是指若v不为根且v的父亲不为根,则将v以及v的子树移到v的父亲的父亲上

要求给出标号方案,操作次数以及方案

n<=1e5

思路:考虑最小的操作次数,每一次操作可能使树的最大深度+1,事实上也存在这样的构造方案:

找到从根下来的最长链,找到深度最大的分叉点u,设最长链的后继为v,u的另一个儿子为w,则将v变成w的儿子

具体实现的时候可以用cnt记录当前节点上一个兄弟的最后一条链的深度

 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  200010
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 
29 const ll MOD=1e9+7,inv2=(MOD+1)/2;
30       double eps=1e-6;
31       int dx[4]={-1,1,0,0};
32       int dy[4]={0,0,-1,1};
33 
34 int head[N],vet[N],nxt[N],f[N],d[N],c[N],id[N],son[N],tot,cnt,ans,s;
35 
36 int read()
37 {
38    int v=0,f=1;
39    char c=getchar();
40    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
41    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
42    return v*f;
43 }
44 
45 void add(int a,int b)
46 {
47     nxt[++tot]=head[a];
48     vet[tot]=b;
49     head[a]=tot;
50 }
51 
52 void dfs(int u)
53 {
54     id[++s]=u;
55     rep(i,1,cnt) c[++ans]=u;
56     cnt=0;
57     int e=head[u];
58     while(e)
59     {
60         int v=vet[e];
61         if(v!=son[u]) dfs(v);
62         e=nxt[e];
63     }
64     if(son[u]) dfs(son[u]);
65     cnt++;
66 }
67 
68 int main()
69 {
70     int n=read(); d[1]=1;
71     rep(i,1,n) head[i]=0;
72     tot=0;
73     rep(i,2,n)
74     {
75         int x=read()+1;
76         f[i]=x;
77         d[i]=d[x]+1;
78         add(x,i);
79     }
80     int k=1;
81     rep(i,1,n)
82      if(d[i]>d[k]) k=i;
83     while(k>1)
84     {
85         son[f[k]]=k;
86         k=f[k];
87     }
88     s=ans=0;
89     dfs(1);
90     rep(i,1,n) printf("%d ",id[i]-1);
91     printf("\n");
92     printf("%d\n",ans);
93     rep(i,1,ans) printf("%d ",c[i]-1);
94     return 0;
95 }

 

posted on 2019-10-28 15:43  myx12345  阅读(255)  评论(0编辑  收藏  举报

导航