190482025-11-18 21:00:24kukkermanHírlánccpp17Elfogadva 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;
}
RészfeladatÖsszpontTesztVerdiktIdőMemória
subtask10/0
1Elfogadva1ms316 KiB
subtask220/20
2Elfogadva2ms316 KiB
3Elfogadva2ms316 KiB
4Elfogadva2ms316 KiB
5Elfogadva2ms512 KiB
6Elfogadva2ms316 KiB
7Elfogadva1ms316 KiB
8Elfogadva2ms316 KiB
9Elfogadva2ms316 KiB
10Elfogadva2ms316 KiB
11Elfogadva1ms316 KiB
12Elfogadva1ms316 KiB
subtask318/18
13Elfogadva78ms3380 KiB
14Elfogadva79ms3496 KiB
15Elfogadva79ms3380 KiB
16Elfogadva81ms3496 KiB
17Elfogadva79ms3372 KiB
18Elfogadva79ms3380 KiB
19Elfogadva81ms3380 KiB
20Elfogadva79ms3504 KiB
21Elfogadva79ms3380 KiB
22Elfogadva85ms3500 KiB
subtask442/42
23Elfogadva1ms316 KiB
24Elfogadva2ms316 KiB
25Elfogadva2ms316 KiB
26Elfogadva2ms316 KiB
27Elfogadva2ms512 KiB
28Elfogadva2ms316 KiB
29Elfogadva1ms316 KiB
30Elfogadva2ms316 KiB
31Elfogadva2ms316 KiB
32Elfogadva2ms316 KiB
33Elfogadva1ms316 KiB
34Elfogadva1ms316 KiB
35Elfogadva78ms3380 KiB
36Elfogadva79ms3496 KiB
37Elfogadva79ms3380 KiB
38Elfogadva81ms3496 KiB
39Elfogadva79ms3372 KiB
40Elfogadva79ms3380 KiB
41Elfogadva81ms3380 KiB
42Elfogadva79ms3504 KiB
43Elfogadva79ms3380 KiB
44Elfogadva85ms3500 KiB
45Elfogadva78ms3496 KiB
46Elfogadva78ms3380 KiB
47Elfogadva78ms3380 KiB
48Elfogadva78ms3496 KiB
49Elfogadva78ms3380 KiB
50Elfogadva78ms3380 KiB
51Elfogadva78ms3380 KiB
52Elfogadva78ms3504 KiB
53Elfogadva79ms3384 KiB
54Elfogadva78ms3380 KiB