• 【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("
    ");
    92     printf("%d
    ",ans);
    93     rep(i,1,ans) printf("%d ",c[i]-1);
    94     return 0;
    95 }
  • 相关阅读:
    QT学习——dialog、widget、mainwindow的区别和选择
    剑指offer——二叉树的深度
    位运算实现加减乘除四则运算
    剑指offer——求两个整数和
    C++常用设计模式
    从编程实现角度学习 Faster R-CNN(附极简实现)
    剑指offer——最小的k个数
    剑指offer——对称二叉树
    java 定时器
    rocketmq consumer接收到的MessageExt中各个字段的说明
  • 原文地址:https://www.cnblogs.com/myx12345/p/11752739.html
Copyright © 2020-2023  润新知