zoukankan      html  css  js  c++  java
  • [agc004D]Teleporter

    Description 

    传送门

     Solution

    依题意我们可以知道,以2-n为出发点的边和1号节点会构成一课树(不然2-n号节点无法都达到首都)。

    为了让2-n号节点中,离1号节点的距离<k的能够使到1号点到路径长为k(>k的先不讨论),我们需要1号节点的边指向自己。(否则1号节点会和某些点组成一个环,由于环的大小>1,距离<k的点只能不断给路径长度加上环的大小,总是会有这样的点路径长不能等于k)

    至于>k的点,我们就考虑贪心强拆,从下往上贪心。如果当前处理到了一棵深度=k-1的子树(设子树根节点深度1)则需要把这棵子树拆出来(其实是让子树根节点出发的边指向首都),当然根节点要特判。

    其实贪心也可以从上往下。但是从下往上才能够得到最优解。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int n,k,a[100010],dep[100010],maxn[100100],ans;
    struct node{int y,nxt;
    }g[100010];int h[100010];
    void dfs(int x)
    {
        for (int i=h[x];i;i=g[i].nxt)
        if (g[i].y!=x)
        {
            dep[g[i].y]=dep[x]+1;
            dfs(g[i].y);
            maxn[x]=max(maxn[x],maxn[g[i].y]);
        }
        maxn[x]=max(maxn[x],dep[x]);
        if (x==1) return;
        if (maxn[x]-dep[x]>=k-1&&a[x]!=1||(maxn[x]-dep[x]>=k)) maxn[x]=0,ans++;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        scanf("%d",&a[1]);
        for (int i=2;i<=n;i++) 
        {
            scanf("%d",&a[i]);    
            g[i]=node{i,h[a[i]]};h[a[i]]=i;    
        }
        ans=0;
        dfs(1);
        if (a[1]!=1) ans++;
        printf("%d",ans);
    }
  • 相关阅读:
    UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)
    HDOJ(HDU).1412 {A} + {B} (STL SET)
    UVA.10474 Where is the Marble ( 排序 二分查找 )
    HDOJ(HDU).1754 I Hate It (ST 单点替换 区间最大值)
    HDOJ(HDU).1166 敌兵布阵 (ST 单点更新 区间求和)
    17 西安
    17 沈阳
    13 南京
    10/11 作战会议
    2019牛客国庆集训派对day5
  • 原文地址:https://www.cnblogs.com/coco-night/p/9493080.html
Copyright © 2011-2022 走看看