AtCoder Context ABC 167- D - Teleporter

运行要求
运行时间限制: 2sec
内存限制: 1024MB
原文链接

题目
高桥王国拥有N座城市。这些城市的编号由1到N。
在这些城市中,每一座城市拥有一道传送门。城市i的传送门的目的地是城市Ai。
高桥王喜欢正整数K。人性的高桥王想知道,从城市1出发,使用K个传送门以后,正好到达哪一座城市。
请你为高桥国王编写程序。

输入前提条件

  • 2<=N<=2*10^5
  • 1<=Ai<=N
  • 1<=K<=10^18

输入
输入都以以下标准从命令行输入

N K
A1 A2 A3 A4...An

输出
输出从城市1出发,使用K次传送门后正好到达的城市


例1
输入

4 5
3 2 4 1

输出

4

从城市1出发,使用5次传送门的话,以1->3->4->1->3->4的顺序移动

例2
输入

6 727202214173249351
6 5 2 5 3 2

输出

2

读懂题目
传送门可以看作一个节点,一个传送门可以传送到另外一个城市,而且仅仅能传送到一个城市。我们可以把节点和节点之间的关系看成是单向的。
如例1,我们可以把输入抽象成下面的节点图。
AtCoder Context ABC 167- D - Teleporter_第1张图片
解题思路
我们可以看到,这个节点图有那么几个特点

1个节点只能通向另外一个节点。比如A->B代表A通向B,那么只会存在A->B,不会存在A->C

节点和节点之间的指向是单一方向的,比如A->B代表节点A通向B,除非B专门指向A才会有B->A

中间可能会形成环形
AtCoder Context ABC 167- D - Teleporter_第2张图片

因为节点只通向另外一个节点而不是另外多个节点,所以环状只能有一个

K的值特别大,最大可能达到10^18,所以一定是通过计算得到的。

K的值可能很小,还没有到环上,这种情况下直接求出
AtCoder Context ABC 167- D - Teleporter_第3张图片

K的值可能比较大,到达了环上,那么这种情况我们可以通过K的值和环的周长,取余来计算最终到达环的哪个地
AtCoder Context ABC 167- D - Teleporter_第4张图片

可以用dfs来遍历,遍历到环的末尾的时候,停止遍历。

可以把遍历图中得到的值放在一个队列里面。

代码

import sys
sys.setrecursionlimit(100000000)

N,K = map(int,input().split())
ARR = list(map(int,input().split()))
NodeStatus = [False] * N
NodeFirstSteps = [0] * N
L = 0
STARTLINDEX = 0
OrderARR = []


def dfs(pos, arr, step):
    if NodeStatus[pos] == True:
        L = (step - NodeFirstSteps[pos])
        STARTLINDEX = NodeFirstSteps[pos]
        print(OrderARR[(K - STARTLINDEX) % L + STARTLINDEX] + 1)
        return

    if step == K:
        print(pos+1)
        return

    OrderARR.append(pos)
    NodeStatus[pos] = True
    NodeFirstSteps[pos] = step
    dfs(arr[pos] - 1, arr, step + 1)


dfs(0, ARR, 0)

总结
这道题考察了对dfs的应用。在dfs的遍历过程中如何求出环的周长是对dfs的应用考察最多的地方

※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
二维码.jpg


你可能感兴趣的:(python3.x,dfs,算法,树形结构)