Submission #1330829

#TimeUsernameProblemLanguageResultExecution timeMemory
1330829SSKMFDžumbus (COCI19_dzumbus)C++20
30 / 110
20 ms1328 KiB
#include <bits/stdc++.h>
using namespace std;

vector <int> adiacenta[101];
int64_t minim[101][101][3] , __minim[101];
bool vizitat[101];
int necesar[101];

int Parcurgere (const int nod , const int sursa)
{
    int cantitate = 1;
    vizitat[nod] = true;
    minim[nod][0][0] = 0;
    minim[nod][0][1] = necesar[nod];
    minim[nod][0][2] =  minim[nod][1][0] = minim[nod][1][1] = minim[nod][1][2] = 1000000000000000LL;
    for (auto& vecin : adiacenta[nod]) {
        if (vecin != sursa)
        {
            const int termen = Parcurgere(vecin , nod);
            for (int indice = cantitate + 1 ; indice <= cantitate + termen ; indice++)
                { minim[nod][indice][0] = minim[nod][indice][1] = minim[nod][indice][2] = 1000000000000000LL; }

            for (int luat = cantitate + termen ; luat ; luat--) {
                for (int anterior = min(cantitate , luat) ; anterior >= max(0 , luat - termen) ; anterior--)
                {
                    minim[nod][luat][0] = min(minim[nod][luat][0] , minim[nod][anterior][0] + min({minim[vecin][luat - anterior][0] , minim[vecin][luat - anterior][1] , minim[vecin][luat - anterior][2]}));
                    minim[nod][luat][1] = min(minim[nod][luat][1] , minim[nod][anterior][1] + minim[vecin][luat - anterior][0]);
                    minim[nod][luat][2] = min(minim[nod][luat][2] , minim[nod][anterior][2] + min(minim[vecin][luat - anterior][0] , minim[vecin][luat - anterior][2]));

                    if (luat > anterior)
                        { minim[nod][luat][2] = min(minim[nod][luat][2] , minim[nod][anterior][2] + minim[vecin][luat - anterior - 1][1]); }

                    if (anterior)
                    {
                        minim[nod][luat][2] = min(minim[nod][luat][2] , minim[nod][anterior - 1][1] + minim[vecin][luat - anterior][2]);
                        
                        if (luat > anterior)
                            { minim[nod][luat][2] = min(minim[nod][luat][2] , minim[nod][anterior - 1][1] + minim[vecin][luat - anterior - 1][1]); }
                    }
                }
            }

            cantitate += termen;
        }
    }

    return cantitate;
}

inline void Solve ()
{
    int numar_noduri , numar_muchii;
    cin >> numar_noduri >> numar_muchii;
    
    for (int nod = 1 ; nod <= numar_noduri ; nod++)
        { cin >> necesar[nod]; }

    while (numar_muchii--)
    {
        int nod[2]; cin >> nod[0] >> nod[1];
        adiacenta[nod[0]].push_back(nod[1]);
        adiacenta[nod[1]].push_back(nod[0]);
    }

    int cantitate = 0;
    for (int nod = 1 ; nod <= numar_noduri ; nod++) {
        if (!vizitat[nod])
        { 
            const int termen = Parcurgere(nod , 0);
            for (int indice = cantitate + 1 ; indice <= cantitate + termen ; indice++)
                { __minim[indice] = 1000000000000000LL; }

            for (int luat = cantitate + termen ; luat ; luat--) {
                for (int anterior = min(cantitate , luat) ; anterior >= max(0 , luat - termen) ; anterior--)
                    { __minim[luat] = min(__minim[luat] , __minim[anterior] + min({minim[nod][luat - anterior][0] , minim[nod][luat - anterior][1] , minim[nod][luat - anterior][2]})); }
            }

            cantitate += termen;
        }
    }

    int numar_intrebari;
    cin >> numar_intrebari;

    while (numar_intrebari--)
    {
        int limita;
        cin >> limita;

        if (limita < __minim[2])
            { cout << "0\n"; continue; }

        int stanga = 2 , dreapta = numar_noduri;
        while (stanga <= dreapta)
        {
            const int candidat = (stanga + dreapta) >> 1;
            if (__minim[candidat] <= limita) { stanga = candidat + 1; }
            else { dreapta = candidat - 1; }
        }

        cout << dreapta << '\n';
    }
}

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

    int numar_teste = 1;
    // cin >> numar_teste;
    while (numar_teste--)
        { Solve(); }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...