zoukankan      html  css  js  c++  java
  • [AGC004D] Teleporter [贪心]

    题面:

    传送门

    思路:

    分析可知,这道题中的图是一个环套内向树,首都在环上

    首先有一个结论:当首都的出边指向首都时,一定最优(不然首都出发可能无法按时到达首都)(可以按时到达的情况也一定有到不了的)

    这种情况下首都构成自环,其他边构成一棵指向首都的树

    因此可以这样贪心地解决问题:

    从所有的叶节点开始拓扑排序,记录每一个节点下属的深度最大的叶节点的深度

    如果有一个节点的距离(上述深度)到达了k-1,那么就把这个节点拆下来接到首都上面,剩下的节点继续作为新叶节点拓扑排序

    这样所有1的子树的深度都在k以内,到达首都以后可以走自环达到k

    Code:

     1     #include<iostream>
     2     #include<cstdio>
     3     #include<cstring>
     4     #include<algorithm>
     5     using namespace std;
     6     inline int read(){
     7         int re=0,flag=1;char ch=getchar();
     8         while(ch>'9'||ch<'0'){
     9             if(ch=='-') flag=-1;
    10             ch=getchar();
    11         }
    12         while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    13         return re*flag;
    14     }
    15     int n,K,a[100010],dep[100010];
    16     int q[100010],head=0,tail=0,cnt[100010];
    17     int main(){
    18         int i,u,ans=0;
    19         n=read();K=read();
    20         a[1]=read();
    21         if(a[1]!=1) ans++,a[1]=1;
    22         for(i=2;i<=n;i++) a[i]=read(),cnt[a[i]]++;
    23     //    for(i=1;i<=n;i++) cout<<cnt[i]<<ends;cout<<endl;
    24         for(i=1;i<=n;i++) if(!cnt[i]) q[tail++]=i;
    25         while(head<tail){
    26             u=q[head++];
    27     //        cout<<"topo "<<u<<ends<<dep[u]<<endl;
    28             if(u==1) break;
    29             if(a[u]!=1&&dep[u]==K-1) ans++;
    30             else dep[a[u]]=max(dep[a[u]],dep[u]+1);
    31             cnt[a[u]]--;
    32             if(cnt[a[u]]==0) q[tail++]=a[u];
    33         }
    34         printf("%d
    ",ans);
    35     }
  • 相关阅读:
    每日总结
    团队冲刺9
    团队冲刺8
    团队冲刺7
    团队冲刺6
    团队冲刺5
    团队冲刺4
    团对冲刺3
    团队冲刺2
    每日博客
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8467643.html
Copyright © 2011-2022 走看看