Cod sursa(job #2549346)

Utilizator danbesuDan Besu danbesu Data 17 februarie 2020 17:05:24
Problema Asmax Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.1 kb
/*
 siruri: cost
         tati: pastrez predecesorul fiecarui nod - DFS
         suma: suma pana la acel nod - o actualizez in trecerea finala ( elimin nodurile cu cost negativ)
         nivel: nivelul fiecarui nod in arbore
*/
#include <iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;

ifstream in("asmax.in");
ofstream out("asmax.out");

struct level{
    int val, lvl;
};

int n, nr_poz = 0, lvl_count = 1;
int tata[16001];
bool viz[16001];

vector<int>graf[16001];
vector<int>cost;
vector<level>nivele;
queue<int>c;

void DFS_tata(int nod){
    viz[nod] = true;

    for(int i = 0; i< graf[nod].size(); ++i){
        int vecin = graf[nod][i];
        if(viz[vecin] == false){
            tata[vecin] = nod;
            viz[vecin] = true;
            DFS_tata(vecin);
        }
    }
}

void BFS_nivele(int start){
    c.push(start); /// introduc primul nod in coada
    viz[start] = 1;/// il marchez
    level n1;
    n1.val = 0, n1.lvl = 0; nivele.push_back(n1);
    n1.val = 1, n1.lvl = 1; nivele.push_back(n1); ///introduc in vectorul de nivele primul nod

    while(!c.empty()){
        int nod_curent = c.front();
        c.pop();
        ++lvl_count;
        for(int i = 0; i<graf[nod_curent].size(); ++i){
            int vecin = graf[nod_curent][i];
            if(viz[vecin] == false){
                level nod_nou;
                nod_nou.val = vecin;
                nod_nou.lvl = lvl_count;
                nivele.push_back(nod_nou);
                c.push(vecin);
                viz[vecin] = true;
            }
        }
    }
}

int main()
{
    ///citirea costurilor, aflarea costului maxim si numarul de costuri pozitive
    in>>n;
    cost.push_back(0);
    int nr_poz = 0, cost_max = -1001;
    for(int i = 1; i<=n; ++i){
        int c; in>>c;
        cost.push_back(c);
        if(c>=-1)
            ++nr_poz;
        cost_max = max(cost_max, c);
    }

    /// citirea grafului neorientat
    for(int i = 1; i<=n; ++i){
        int a, b; in>>a>>b;
        graf[a].push_back(b);
        graf[b].push_back(a);
    }

    if(nr_poz <=1){
        out<<cost_max;
        return 0;
    }

    tata[1] = 0; /// nodul 1 e radacina
    DFS_tata(1); ///formez vector de tati

    /*for(int i = 1; i<=n; ++i)
        cout<<tata[i]<<' ';
    cout<<'\n';*/

    for(int i = 1; i<=n; ++i) /// refac vectorul viz 0, pentru BFS
        viz[i] = false;

    BFS_nivele(1); ///formez vector de nivele
    /*for(int i = 1; i<=n; ++i)
        cout<<nivele[i].val<<'-'<<nivele[i].lvl << '\n';*/

    int suma_max = -1001;
    for(int i = nivele.size() - 1; i>=1; --i){
        int nod_curent = nivele[i].val;
        int suma = cost[nod_curent];

        for(int j = 0; j < graf[nod_curent].size(); ++j){
            int vecin = graf[nod_curent][j];
            if(vecin != tata[nod_curent] && cost[vecin] >= 0){
                suma += cost[vecin];
            }
        }
        suma_max = max(suma, suma_max);

    }
    out<<suma_max;

    in.close();
    out.close();
    return 0;
}