22492023-01-05 19:08:10sztomiTom és Jerry 3cpp11Hibás válasz 9/50136ms13544 KiB
#include <bits/stdc++.h>

using namespace std;

struct irany_ut{
    int pont;
    int hossz;

    irany_ut(int p=-1, int h=0) : pont(p), hossz(h) {}
};

struct comp{
    bool operator()(irany_ut a, irany_ut b){
        if(a.hossz == b.hossz)
            return a.pont < b.pont;
        return a.hossz > b.hossz;
    }
};

int n, k;
vector<vector<int>> graf;
vector<int> tom_tav;
vector<int> jerry_tav;
// ket legtavolabbi az adott pontbol
vector<pair<irany_ut, irany_ut>> legtavolabbi;

void tavot_allit(int akt, int elozo, vector<int>& tavok){
    for(int kov : graf[akt]){
        if(kov == elozo) continue;
        tavok[kov] = tavok[akt] + 1;
        tavot_allit(kov, akt, tavok);
    }
}

// csak a fa adott allasaban a pont alatt levo utakat veszi figyelembe
void legtavolabbit_allit_alatta(int akt, int elozo){
    for(int kov : graf[akt]){
        if(kov == elozo) continue;
        legtavolabbit_allit_alatta(kov, akt);

        set<irany_ut, comp> sorrend;
        sorrend.insert(legtavolabbi[akt].first);
        sorrend.insert(legtavolabbi[akt].second);
        irany_ut ideigl(kov, legtavolabbi[kov].first.hossz+1);
        sorrend.insert(ideigl);
        legtavolabbi[akt].first = *sorrend.begin();
        sorrend.erase(sorrend.begin());
        legtavolabbi[akt].second = *sorrend.begin();
    }
}

// az alatta levo leghosszabbak segitsegevel kiszamolja a felette levo utakbol is a leghosszabbakat
void legtavolabbit_allit(int akt, int elozo){
    if(elozo != -1){
        set<irany_ut, comp> sorrend;
        sorrend.insert(legtavolabbi[akt].first);
        sorrend.insert(legtavolabbi[akt].second);
        irany_ut ideigl;
        if(legtavolabbi[elozo].first.pont == akt){
            ideigl = irany_ut(elozo, legtavolabbi[elozo].second.hossz+1);
        }
        else{
            ideigl = irany_ut(elozo, legtavolabbi[elozo].first.hossz+1);
        }
        sorrend.insert(ideigl);
        legtavolabbi[akt].first = *sorrend.begin();
        sorrend.erase(sorrend.begin());
        legtavolabbi[akt].second = *sorrend.begin();
    }


    for(int kov : graf[akt]){
        if(kov == elozo) continue;
        legtavolabbit_allit(kov, akt);
    }
}

void megold(){
    int tom_kezd, jerry_kezd;
    cin >> n >> tom_kezd >> jerry_kezd >> k;
    graf.assign(n+1, vector<int>());
    tom_tav.assign(n+1, -1);
    jerry_tav.assign(n+1, -1);
    legtavolabbi.assign(n+1, {irany_ut(), irany_ut()});
    int a, b;
    for(int i = 0; i < n-1; i++){
        cin >> a >> b;
        graf[a].push_back(b);
        graf[b].push_back(a);
    }
    tom_tav[tom_kezd] = 0;
    tavot_allit(tom_kezd, -1, tom_tav);
    jerry_tav[jerry_kezd] = 0;
    tavot_allit(jerry_kezd, -1, jerry_tav);

    // ha Tom rogton kezdes utan elkapja Jerryt
    if(tom_tav[jerry_kezd] <= 1){
        cout << "IGEN\n";
        return;
    }

    // eloszor az alatta levokbol a ket legtavolabbit beallitjuk az osszesnek
    // utana, meg az egyestol odavezeto uton a felette levok kozul a nem felejuk meno agbol allitjak be
    // jo lenne tudni, hogy egy adott pontbol egy szomszedja fele indulva mennyi a leghosszabb ut
    // akkor, amikor nezzuk egy masik szomszedjat
    legtavolabbit_allit_alatta(1, -1);
    legtavolabbit_allit(1, -1);
/*
    for(int i = 1; i <= n; i++){
        cout << "pont: " << i << " ------------\n";
        cout << "elso: pont " << legtavolabbi[i].first.pont << " hossz " << legtavolabbi[i].first.hossz << "\n";
        cout << "masodik: pont " << legtavolabbi[i].second.pont << " masodik " << legtavolabbi[i].second.hossz << "\n";
        cout << "jerry tav: " << jerry_tav[i] << "\n";
        cout << "tom tav: " << tom_tav[i] << "\n";
    }
*/

    if(2*k+1 > n-1){
        cout << "IGEN\n";
        return;
    }

    bool tom_elkapja = true;
    for(int i = 1; i <= n; i++){
        // ha el elkapna Tom Jerryt egy adott pontban
        if(tom_tav[i]-1 <= jerry_tav[i]) continue;

        // ha Jerry egy megfeleloen hosszu utra jut
        if(legtavolabbi[i].first.hossz + legtavolabbi[i].second.hossz >= 2*k+1){
            tom_elkapja = false;
        }
    }

    cout << (tom_elkapja ? "IGEN" : "NEM") << "\n";
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int t;
    cin >> t;
    while(t--){
        megold();
    }
}
RészfeladatÖsszpontTesztVerdiktIdőMemória
base9/50
1Elfogadva0/03ms1832 KiB
2Elfogadva0/02ms2060 KiB
3Elfogadva5/52ms2228 KiB
4Hibás válasz0/13ms2456 KiB
5Hibás válasz0/13ms2536 KiB
6Hibás válasz0/13ms2532 KiB
7Hibás válasz0/13ms2668 KiB
8Hibás válasz0/13ms2872 KiB
9Hibás válasz0/13ms2948 KiB
10Hibás válasz0/13ms2956 KiB
11Hibás válasz0/23ms2836 KiB
12Hibás válasz0/23ms2816 KiB
13Hibás válasz0/13ms3172 KiB
14Hibás válasz0/2136ms6556 KiB
15Hibás válasz0/2116ms5132 KiB
16Hibás válasz0/2135ms6636 KiB
17Hibás válasz0/2131ms8580 KiB
18Hibás válasz0/2136ms6968 KiB
19Elfogadva2/2133ms7228 KiB
20Elfogadva2/298ms13544 KiB
21Hibás válasz0/2119ms5740 KiB
22Hibás válasz0/2114ms5828 KiB
23Hibás válasz0/3133ms9460 KiB
24Hibás válasz0/2136ms7376 KiB
25Hibás válasz0/3131ms7700 KiB
26Hibás válasz0/2135ms10248 KiB
27Hibás válasz0/2118ms5960 KiB
28Hibás válasz0/3115ms6092 KiB