190482025-11-18 21:00:24kukkermanHírlánccpp17Accepted 80/8085ms3504 KiB
#include <iostream>
#include <vector>

// Beolvassa a bemenetrol az egyes tanulokhoz tartozo kovetkezo tanulo sorszamat.
// A szamozast ugyanugy 1-tol kezdodoen taroljuk, mint ahogy a bemenetben szerepel.
std::vector<int> beolvas(std::istream &be) {
    int n;
    be >> n;

    // Eggyel tobb elemet foglalunk le a tombben, hogy 1-tol kezdodoen szamozhassuk
    // a tanulokat, igy a 0. elemet nem hasznaljuk majd.
    std::vector<int> kov(n + 1);
    for (int i = 1; i <= n; i++) {
        be >> kov[i];
    }

    return kov;
}

// A bejaras soran az egyes tanuloknak haromfele allapota lehet:
//   - Ismeretlen:   meg nem inditottuk bejarast az adott tanulotol kezdodoen
//   - Felfedezett:  az adott tanulot az eppen folyamatban levo bejaras soran fedeztuk fel
//   - Feldolgozott: az adott tanulo eseten mar ismerjuk, hogy tole kiindulva
//                   osszesen hany tanulohoz jut el a hir
enum class Allapot {
    Ismeretlen,
    Felfedezett,
    Feldolgozott
};

// Egy tanulo adatait tarolo struktura
struct Tanulo {
    // A bejarasok soran a tanulo allapota
    Allapot allapot = Allapot::Ismeretlen;

    // Egy bejaras soran ennyi lepessel jut el a tanulohoz a hir
    int sorszam = -1;

    // Ha a tanulotol indul ki egy hir, akkor osszesen ennyi tanulohoz jut el, a kiindulo
    // tanulot is beleszamitva.
    int letszam = 0;
};

// Meghatarozza minden tanulohoz, hogy tole kiindulva osszesen hany tanulohoz jut el a hir.
void feldolgoz(const std::vector<int> &kov) {
    const int n = static_cast<int>(kov.size());

    // Letrehozzuk minden tanulohoz a korabban deklaralt strukturat.
    std::vector<Tanulo> t(n);

    // Annak a tanulonak a sorszama, akitol kiindulva a legtobb tanulohoz jut el egy hir.
    int max_tanulo = 0;

    // Megprobalunk minden tanulotol elinditani egy hirt.
    for (int i = 1; i < n; i++) {
        // Csak abban az esetben inditjuk el a tenyleges bejarast, ha az aktualis tanulo
        // eseten meg nem hataroztuk meg a letszamot.
        if (t[i].allapot == Allapot::Ismeretlen) {
            // Elinditunk egy bejarast az 'i'. tanulotol kiindulva, es addig haladunk,
            // ami el nem erunk egy olyan tanulohoz, akivel mar talalkoztuk akar egy korabbi,
            // akar az epp aktualis bejaras soran.

            // A bejaras soran az aktualis tanulo sorszama
            int j = i;
            // Az aktualis tanulohoz ennyi lepesben er el a hir
            int h = 0;
            // A bejaras soran az aktualis tanulot megelozo tanulo sorszama
            int elozo = -1;
            while (t[j].allapot == Allapot::Ismeretlen) {
                // Az aktualis tanulo allapotat 'Felfedezett'-re allitjuk
                t[j].allapot = Allapot::Felfedezett;
                // Az bejaras soran 'h' lepesbol jutunk el az 'i'. tanulotol az aktualisig. 
                t[j].sorszam = h;
                // Elmentjuk az aktualis tanulo sorszamat, mivel kesobb meg szuksegunk lesz
                // a bejaras szemszogebol vett utolso elotti tanulora.
                elozo = j;
                // Kikeressuk a kovetkezo tanulo sorszamat.
                j = kov[j];
                // Noveljuk a lepesek szamat.
                h++;
            }

            // A bejaras soran ennyi tanulohoz jut el az hir.
            int ossz_letszam = 0;

            if (t[j].allapot == Allapot::Felfedezett) {
                // Ha egy olyan tanulonal all meg a bejaras, akit az aktualis bejaras soran
                // fedeztunk fel, akkor ez azt jelenti, hogy talaltunk egy uj kort, amelynek
                // a 'j'. tanulo biztosan a tagja.
                
                // Ennyi lepesbol erjuk el a kort.
                const int bevezeto_hossza = t[j].sorszam;
                // Ennyi tanulobol all a felfedezett kor.
                const int kor_hossza = t[elozo].sorszam - t[j].sorszam + 1;

                // Ujbol bejarrjuk a felfedezettt kor, es minden olyan tanulo eseten,
                // akik reszei a felfedezett kornek:
                //   - beallitjuk az allapotat 'Feldolgozott'-ra
                //   - beallitjuk a hozzajuk tartozo letszamot 'kor_hossza'-ra
                int k = j;
                do {
                    t[k].allapot = Allapot::Feldolgozott;
                    t[k].letszam = kor_hossza;
                    k = kov[k];
                } while (k != j);

                // Az 'i'. tanulohoz tartozo letszam egyenlo a kor eleresehez szukseges
                // lepesek szama, plusz a kort alkoto tanulok szamaval.
                ossz_letszam = bevezeto_hossza + kor_hossza;

            } else {
                // A bejaras egy olyan tanulonal allt meg, akinel mar korabban meghataroztuk
                // a letszamot. Ebben az esetben az 'i'. tanulohoz tartozo letszam egyenlo
                // a 'j'. tanulohoz vezeto lepesek szama, plusz a 'j'. tanulohoz tartozo
                // letszammal.
                ossz_letszam = h + t[j].letszam;
            }

            // Ha az 'i'. tanulo tobb tanulot tud elerhi a hirrel, mint az eddigi maximum,
            // akkor innentol kezdve az ove lesz a maximum.
            if (t[max_tanulo].letszam < ossz_letszam) {
                max_tanulo = i;
            }

            // Meghatarozzuk az azon tanulokhoz tartozo letszamot, akiken keresztul
            // a bejaras soran a hir eljut egy mar ismert tanulohoz ('j'. tanulo).
            // Az 'i'. tanulo eseten ezt mar korabban meghataroztuk ('ossz_letszam'),
            // ami minden lepessel eggyel csokken egeszen addig, amig el nem erjuk
            // a 'j'. tanulot.
            for (int k = i; k != j; k = kov[k]) {
                t[k].allapot = Allapot::Feldolgozott;
                t[k].letszam = ossz_letszam;
                ossz_letszam--;
            }
        }
    }

    // Kiiratjuk az eredmenyt a kepernyore.
    std::cout << max_tanulo << ' ' << t[max_tanulo].letszam << '\n';
}

int main() {
    const auto kov = beolvas(std::cin);
    feldolgoz(kov);

    return 0;
}
SubtaskSumTestVerdictTimeMemory
subtask10/0
1Accepted1ms316 KiB
subtask220/20
2Accepted2ms316 KiB
3Accepted2ms316 KiB
4Accepted2ms316 KiB
5Accepted2ms512 KiB
6Accepted2ms316 KiB
7Accepted1ms316 KiB
8Accepted2ms316 KiB
9Accepted2ms316 KiB
10Accepted2ms316 KiB
11Accepted1ms316 KiB
12Accepted1ms316 KiB
subtask318/18
13Accepted78ms3380 KiB
14Accepted79ms3496 KiB
15Accepted79ms3380 KiB
16Accepted81ms3496 KiB
17Accepted79ms3372 KiB
18Accepted79ms3380 KiB
19Accepted81ms3380 KiB
20Accepted79ms3504 KiB
21Accepted79ms3380 KiB
22Accepted85ms3500 KiB
subtask442/42
23Accepted1ms316 KiB
24Accepted2ms316 KiB
25Accepted2ms316 KiB
26Accepted2ms316 KiB
27Accepted2ms512 KiB
28Accepted2ms316 KiB
29Accepted1ms316 KiB
30Accepted2ms316 KiB
31Accepted2ms316 KiB
32Accepted2ms316 KiB
33Accepted1ms316 KiB
34Accepted1ms316 KiB
35Accepted78ms3380 KiB
36Accepted79ms3496 KiB
37Accepted79ms3380 KiB
38Accepted81ms3496 KiB
39Accepted79ms3372 KiB
40Accepted79ms3380 KiB
41Accepted81ms3380 KiB
42Accepted79ms3504 KiB
43Accepted79ms3380 KiB
44Accepted85ms3500 KiB
45Accepted78ms3496 KiB
46Accepted78ms3380 KiB
47Accepted78ms3380 KiB
48Accepted78ms3496 KiB
49Accepted78ms3380 KiB
50Accepted78ms3380 KiB
51Accepted78ms3380 KiB
52Accepted78ms3504 KiB
53Accepted79ms3384 KiB
54Accepted78ms3380 KiB