AtCoder Grand Contest 004 Teleporter (拓扑排序)

 Teleporter

时间限制: 1 Sec   内存限制: 256 MB
提交: 75   解决: 15
[ 提交][ 状态][ 讨论版][命题人: admin]

题目描述

There are N towns in Snuke Kingdom, conveniently numbered 1 through N. Town 1 is the capital.

Each town in the kingdom has a Teleporter, a facility that instantly transports a person to another place. The destination of the Teleporter of town i is town ai (1≤ai≤N). It is guaranteed that one can get to the capital from any town by using the Teleporters some number of times.

King Snuke loves the integer K. The selfish king wants to change the destination of the Teleporters so that the following holds:

Starting from any town, one will be at the capital after using the Teleporters exactly K times in total.
Find the minimum number of the Teleporters whose destinations need to be changed in order to satisfy the king's desire.

Constraints
2≤N≤105
1≤ai≤N
One can get to the capital from any town by using the Teleporters some number of times.
1≤K≤109

输入

The input is given from Standard Input in the following format:

N K
a1 a2 … aN

输出

Print the minimum number of the Teleporters whose destinations need to be changed in order to satisfy King Snuke's desire.

样例输入

3 1

2 3 1

样例输出

2

提示

Change the destinations of the Teleporters to a=(1,1,1).

来源


[思路]

    改变K 次, 的话,  首先先把 1 到非 1   ans++ ;

    然后 做类似拓扑排序,  BFS 或DFS 搜一遍  统计深度,   相当于 一棵树,从叶子节点扫到 根节点;

    判断 路径上每个节点深度是否为 k-1   如果为k-1   那么 ans++;


[code]


#include <iostream>
#include <stdio.h>
#include <bits/stdc++.h>
typedef long long ll;

const int MAXN=1e5+5;
const int mod =1e9+7;
using namespace std;

int cot[MAXN];
int nex[MAXN];
int deq[MAXN];
int main()
{
    memset(cot,0,sizeof(cot));
    memset(nex,0,sizeof(nex));
    memset(deq,0,sizeof(deq));
    int n,k;
    cin>>n>>k;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        if(i==1&&x!=1)
        {
            ans++;
            continue;
        }
        else
        {
            nex[i]=x;
            cot[x]++;
        }
    }
    queue<int>Q;
    int t=0,h=0;

    for(int i=2;i<=n;i++)
        if(!cot[i])
            Q.push(i);
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        if(u==1)
            break;

        if( nex[u]!=1&&deq[u]==(k-1) )
            ans++;
        else
            deq[nex[u]] =max(deq[nex[u]],deq[u]+1);
        cot[ nex[u] ]--;
        if(!cot[ nex[u] ])
            Q.push( nex[u]);
    }
    cout<<ans<<endl;
    return 0;
}

12

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值