「NOIP2015 提高组」信息传递

内存限制:128 MiB时间限制:1000 ms标准输入输出

题目类型:传统评测方式:文本比较

题目描述

有  个同学(编号为  到 )正在玩一个信息传递的游戏。在游戏里每人都有一个固定的信息传递对象,其中,编号为  的同学的信息传递对象是编号为  的同学。游戏开始时,每人都只知道自己的生日。之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象)。当有人从别人口中得知自己的生日时,游戏结束。请问该游戏一共可以进行几轮?

输入格式

输入共  行。

第  行包含  个正整数 ,表示  个人。
第  行包含  个用空格隔开的正整数 ,其中第  个整数表示编号为  的同学的信息传递对象是编号为  的同学, 且 。

数据保证游戏一定会结束。

输出格式

输出共  行,包含  个整数,表示游戏一共可以进行多少轮。

样例

样例输入复制

5
2 4 2 3 1

样例输出复制

3

数据范围与提示

对于  的数据,;
对于  的数据,;
对于  的数据,。

分类标签

9018 题目 NOIP 提高组 / CSP-S2 2015 

题解(C++14):

#include <cstdio>
#define min(x, y) ((x) < (y) ? (x) : (y))
using namespace std;
const int SIZE = 400010;
inline int read() {
    int x = 0, opr = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            opr = -opr;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') x = (x * 10) + (ch ^ 48), ch = getchar();
    return x * opr;
}
int n, fa[SIZE], dis[SIZE], ans = 0x7f7f7f7f;
int find(int x) {
    if (fa[x] != x) {
        int tmp = fa[x];
        fa[x] = find(fa[x]), dis[x] += dis[tmp];
    }
    return fa[x];
}
int main() {
    n = read();
    for (int i = 1; i <= n; i++) fa[i] = i;
    for (int i = 1; i <= n; i++) {
        int j = read(), U = find(i), V = find(j);
        if (U == V)
            ans = min(ans, dis[i] + dis[j] + 1);
        else
            fa[U] = V, dis[i] = dis[j] + 1;
    }
    printf("%d", ans);
    return 0;
}

题解(C++ 17 (Clang) ):

/*
Author: Xjrjyy
LANG: C++
PROG: $FileName$
Mail: admin@xjrjyy.cn
Blog: https://blog.xjrjyy.cn/
*/

#include <bits/stdc++.h>
using namespace std;

#define fo(x)                      \
    freopen(#x ".in", "r", stdin); \
    freopen(#x ".out", "w", stdout);
#define mp make_pair
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define fi first
#define se second
#define Size(V) ((int)(V).size())
#define All(V) V.begin(), V.end()
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef unsigned int ui;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template <typename M, typename N>
inline M &umax(M &a, const N &b) {
    return a = max(a, (M)b);
}
template <typename M, typename N>
inline M &umin(M &a, const N &b) {
    return a = min(a, (M)b);
}

namespace FastIO {
char space_char = ' ', endline = '\n';
const int io_max_buf = 1 << 21;
// char io_inbuf[io_max_buf], *io_ip1, *io_ip2;
// inline char gc() {
//     static std::streambuf *inbuf = cin.rdbuf();
//     return (io_ip1 == io_ip2 && (io_ip2 = (io_ip1 = io_inbuf) + inbuf->sgetn(io_inbuf, io_max_buf), io_ip1
//     == io_ip2) ? EOF : *io_ip1++);
// }
inline char gc() { return getchar(); }
char io_outbuf[io_max_buf], *io_op1 = io_outbuf;
inline void io_flush() { fwrite(io_outbuf, 1, io_op1 - io_outbuf, stdout), io_op1 = io_outbuf; }
inline void pc(char c) {
    if (io_op1 == io_outbuf + io_max_buf)
        io_flush();
    *(io_op1++) = c;
}
struct AutoFlush {
    ~AutoFlush() { io_flush(); }
} io_auto_flush;
// inline void pc(char c) { putchar(c); }

#define tl template
#define tn typename
#define ei_t enable_if_t
// TODO: remove_cv
tl<tn T, tn P = remove_cv_t<T>> constexpr bool io_c_v =
    is_same<P, char>::value || is_same<P, signed char>::value || is_same<P, unsigned char>::value;
tl<tn T> struct io_rm_all : remove_all_extents<remove_pointer_t<remove_reference_t<remove_cv_t<T>>>> {};
tl<tn T> using io_rm_all_t = tn io_rm_all<T>::type;
tl<tn T, class Enable = void> struct io_a2p { typedef T type; };
tl<tn T> struct io_a2p<T, ei_t<is_array<T>::value>> : add_pointer<io_rm_all_t<T>> {};
tl<tn T> struct io_is_ap : is_pointer<tn io_a2p<remove_cv_t<T>>::type> {};
tl<tn T> constexpr bool io_ap_v = io_is_ap<T>::value;
tl<tn T> constexpr bool io_ca_v = io_ap_v<remove_reference_t<T>> && io_c_v<io_rm_all_t<T>>;
tl<tn T> constexpr bool io_it_v = is_integral<T>::value || is_same<T, ll>::value || is_same<T, ull>::value;

tl<tn T> ei_t<io_c_v<T>> rd(T &x) {
    do
        x = gc();
    while (isspace(x));
}
tl<tn T> ei_t<io_it_v<T> && !io_c_v<T>> rd(T &x) {
    x = 0;
    bool f = false;
    char c = gc();
    while (!isdigit(c)) f = f || (c == '-'), c = gc();
    while (isdigit(c)) x = x * 10 + c - '0', c = gc();
    x *= (f ? -1 : 1);
}
tl<tn T> ei_t<io_ca_v<T>> rd(T s) { scanf("%s", s); }  // TODO: FastIO
tl<tn M, tn N> ei_t<io_ap_v<M> && io_ap_v<N>> rda(M a, N b) {
    while (a != b) rd(*a), a += a < b ? 1 : -1;
}
tl<tn M, tn N> ei_t<io_ap_v<M> && io_it_v<N>> rda(M a, N b) { return rda(a, a + b); }
tl<tn M, tn N> void rd(pair<M, N> t) { rda(t.first, t.second); }
void rd() {}
tl<tn T, tn... Args> void rd(T &&x, Args &&... args) { rd(forward<T>(x)), rd(args...); }
tl<tn T> T rd() {
    static T x;
    rd(x);
    return x;
}
int rdi() { return rd<int>(); }
ll rdl() { return rd<ll>(); }
// pr
tl<tn T> ei_t<io_c_v<T>> pr(T x) { pc(x); }
tl<tn T> void _pri(T x) {
    if (x >= 10) {
        _pri(x / 10);
    }
    pc((char)(x % 10 + '0'));
}
tl<tn T> ei_t<io_it_v<T> && !io_c_v<T>> pr(T x) {
    if (x < 0) {
        pc('-'), x = -x;
    }
    _pri(x);
}
tl<tn T> ei_t<io_ca_v<T>> pr(T s) {
    while (*s) pr(*s), ++s;
}  // TODO: FastIO
tl<tn T> void prc(T x, char c) { pr(x), pc(c); }
tl<tn M, tn N> ei_t<io_ap_v<M> && io_ap_v<N>> prc(M a, N b, char c) {
    while (a != b) {
        pr(*a), a += a < b ? 1 : -1;
        if (a != b)
            pr(c);
    }
}
tl<tn M, tn N> ei_t<io_ap_v<M> && io_it_v<N>> prc(M a, N b, char c) { return prc(a, a + b, c); }
tl<tn M, tn N> void pra(M a, N b) { prc(a, b, space_char), pc(endline); }  // TODO: c
tl<tn M, tn N> void prc(pair<M, N> t, char c) { prc(t.first, t.second, c); }
tl<tn M, tn N> void pr(pair<M, N> t) { prc(t, space_char); }
void _pr() {}
tl<tn T, tn... Args> void _pr(T x, Args... args) { prc(x, space_char), _pr(args...); }  // TODO: c
tl<tn... Args> void pr(Args... args) { _pr(args...), pc(endline); }
void prn() {}
tl<tn T, tn... Args> void prn(T x, Args... args) { pr(x), prn(args...); }
tl<tn... Args> void prr(Args... args) { prn(args...), pc(endline); }
#undef tl
#undef tn
#undef ei_t
}  // namespace FastIO
using namespace FastIO;

mt19937 rnd((ui)chrono::system_clock::now().time_since_epoch().count());

const int maxn = 2e5 + 5;
const int inf = ~0u >> 2;
const double eps = 1e-8;

int n, fa[maxn], d[maxn], A;

int fd(int u) {
    if (fa[u] == u)
        return u;
    int v = fa[u];
    fa[u] = fd(fa[u]);
    d[u] += d[v];
    return fa[u];
}
void upd(int u, int v) {
    if (fd(u) == fd(v))
        return umin(A, d[v] - d[u] + 1), void();
    fa[u] = v, d[u] = 1;
}

int main() {
    rd(n), A = n;
    for (int i = 1; i <= n; ++i) fa[i] = i;
    for (int u = 1, v; u <= n; ++u) rd(v), upd(u, v);
    pr(A);
    return 0;
}

题解(C++):

#include <iostream>
#include <cstdio>
#define s(x) scanf("%d", &x)
using namespace std;
int n, a[200050], ans = 1 << 21, s[200050], t, id[200050];
bool bo[200050];
int main() {
    s(n);
    for (int i = 1; i <= n; ++i) s(a[i]);
    for (int i = 1, x; i <= n; ++i) {
        x = i, t = 0;
        while (!bo[x]) s[++t] = x, bo[x] = 1, id[x] = t, x = a[x];
        if (id[x])
            ans = min(ans, t - id[x] + 1);
        while (t) id[s[t--]] = 0;
    }
    printf("%d\n", ans);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值