【CodeForces - 1020B】Badge(模拟,图,环)

163 篇文章 1 订阅
81 篇文章 1 订阅

题干:

In Summer Informatics School, if a student doesn't behave well, teachers make a hole in his badge. And today one of the teachers caught a group of nn students doing yet another trick.

Let's assume that all these students are numbered from 11 to nn. The teacher came to student aa and put a hole in his badge. The student, however, claimed that the main culprit is some other student papa.

After that, the teacher came to student papa and made a hole in his badge as well. The student in reply said that the main culprit was student ppappa.

This process went on for a while, but, since the number of students was finite, eventually the teacher came to the student, who already had a hole in his badge.

After that, the teacher put a second hole in the student's badge and decided that he is done with this process, and went to the sauna.

You don't know the first student who was caught by the teacher. However, you know all the numbers pipi. Your task is to find out for every student aa, who would be the student with two holes in the badge if the first caught student was aa.

Input

The first line of the input contains the only integer nn (1≤n≤10001≤n≤1000) — the number of the naughty students.

The second line contains nn integers p1p1, ..., pnpn (1≤pi≤n1≤pi≤n), where pipi indicates the student who was reported to the teacher by student ii.

Output

For every student aa from 11 to nn print which student would receive two holes in the badge, if aa was the first student caught by the teacher.

Examples

Input

3
2 3 2

Output

2 2 3 

Input

3
1 2 3

Output

1 2 3 

Note

The picture corresponds to the first example test case.

When a=1a=1, the teacher comes to students 11, 22, 33, 22, in this order, and the student 22 is the one who receives a second hole in his badge.

When a=2a=2, the teacher comes to students 22, 33, 22, and the student 22 gets a second hole in his badge. When a=3a=3, the teacher will visit students 33, 22, 33 with student 33getting a second hole in his badge.

For the second example test case it's clear that no matter with whom the teacher starts, that student would be the one who gets the second hole in his badge.

题目大意:

在图灵学校,如果一个学生表现不好,老师就会在他的徽章上打一个洞。今天,老师逮到了n名学生在搞恶作剧。

这些学生从1到n编号。老师先逮到了a学生然后在他的徽章上打了个洞。但是这个学生说带头的是另一个学生pa

于是老师又抓住学生pa在他的徽章上也打了个洞。这个学生又说其实是学生ppa在带头搞恶作剧。

这个过程一直持续了好一会儿,不过因为这些学生是有限的,最后老师抓住了一个徽章上已经有一个洞的学生。

在给这个倒霉孩子的徽章上又打了个洞以后,老师觉得有点累,需要蒸个桑拿于是他就不再继续了。

你不知道谁是老师逮到的第一个学生,但是你知道所有的数字pi。对于每一个a,如果第一个被逮到的学生是a,你的任务是找到谁会是徽章上面有两个洞的学生。

解题报告:

    用数组去存这条有向边就行了(因为边数就一条),所以不需要去建图。(当然这题还有一种O(n)的做法)

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
int n,a[MAX];
bool vis[MAX];
int main() 
{
	cin>>n;	
	for(int i = 1; i<=n; i++) cin>>a[i];
	for(int i = 1; i<=n; i++) {
		int cur = i;
		memset(vis,0,sizeof vis);
		while(1) {
			if(vis[cur]) break;
			vis[cur] = 1;
			cur = a[cur];
		}
		printf("%d ",cur);
	}
	return 0 ;
}

这题还有一个O(n)的解法:

  因为不难发现,如果一个节点在一个环上,那么答案就是这个节点。反之,那就是在距离这个节点最近的环首上。对于环的问题我们可以拓扑排序一下,然后用并查集去寻找最近的一个环。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;

int a[MAX], in[MAX], f[MAX];

int getf(int i) {
	return (i==f[i] ? i : f[i] = getf(f[i]));
}

int main() 
{
	int n;
	cin>>n;
	for(int i = 1; i<=n; i++) {
		cin>>a[i];
		in[a[i]]++;
	}
	queue<int> q;
	for(int i = 1; i<=n; i++)f[i] = i;
	for(int i = 1; i<=n; i++)if(in[i]==0)
			q.push(i);
	//做拓扑排序,使得剩下的顶点都在环中
	while(!q.empty()) {
		int cur = q.front();
		q.pop();
		in[a[cur]]--;
		f[cur] = a[cur];
		if(in[a[cur]]==0) q.push(a[cur]);
	}
	for(int i = 1; i<=n; i++) printf("%d ",getf(i));


	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值