Cod sursa(job #1826960)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 11 decembrie 2016 11:12:39
Problema Asmax Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <fstream>
#include <stdint.h>
using namespace std;
fstream f1("asmax.in", ios::in);
fstream f2("asmax.out", ios::out);
int32_t n, val[16001], stiva[16001], cap[16001], v[16001], viz[16001], f[16001], vf=1;
int32_t t[16001], viz2[16001], coada[16001], prim=1, ultim=1, k=1;
const int32_t  inf=999999999;
struct muchie
{
    int x, y;
}muc[16001];
void dfs()
{
    int32_t i, j, s;
    while(vf!=0)
    {
        i=cap[stiva[vf]];
        while((i<cap[stiva[vf]+1])&&(viz[v[i]])) i++;
        if(i==cap[stiva[vf]+1])
            {
                if(!f[stiva[vf]])
                {
                    ///adaugi la suma doar fii cu val pozitive
                    s=0;
                    for(j=1; j<=n; j++)
                        if((t[j]==stiva[vf])&&(val[j]>0)) s+=val[j];
                    val[stiva[vf]]+=s;
                }
                vf--;
            }
        ///daca ai vizitat subarborele nodului stiva [vf] insemana ca trebuie sa te intorci recursiv
        ///inainte de a face asta reactualizezi suma pentru stiva[vf] daca acesta nu este frunza
        ///daca e frunza val ei ramane aceeasi
        else
        {
            vf++;
            stiva[vf]=v[i];
            viz[v[i]]=1;
        }
    }
}
void bfs()
{
    int32_t i;
    while(k!=0)
    {
        for(i=cap[coada[prim]]; i<cap[coada[prim]+1]; i++)
            if(!viz2[v[i]])
        {
            ultim++;
            k++;
            coada[ultim]=v[i];
            viz2[v[i]]=1;
            t[coada[ultim]]=coada[prim];
        }
        prim++;
        k--;
    }
}
int main()
{
    int32_t i, m1 ,m2;
    f1>>n;
    for(i=1; i<=n; i++)
        f1>>val[i];
    ///creezi lista de adiacenta
    for(i=1; i<n; i++)
    {
        f1>>m1>>m2;
        muc[i].x=m1;
        muc[i].y=m2;
        ///in stiva memo temporar gradele nodurilor
        stiva[m1]++;
        stiva[m2]++;
    }
    cap[1]=1;
    for(i=1; i<=n; i++)
    {
        cap[i+1]=cap[i]+stiva[i];
        stiva[i]=cap[i];
    }
    stiva[1]=1;
    ///creezi cap cu ajutorul stivei si apoi copii cap in stiva
    for(i=1; i<n; i++)
    {
        m1=muc[i].x;
        m2=muc[i].y;
        v[stiva[m1]]=m2;
        stiva[m1]++;
        v[stiva[m2]]=m1;
        stiva[m2]++;
    }
    ///in nodul i vrei sa ai in final smax a subarborelui pt care el este radacina
    ///sol va fi maximul dintre valorile acestor noduri
    ///e clar ca trebuie sa incepi modif de jos in sus deci parcurgi arborele recursiv
    ///sau cu stiva
    ///cand ajungi la o frunza, in ea lasi valoarea care era
    ///cand t intorci recursiv nodul tau ia val: val nod+ val pozitive ale fiilor- adica subarborilor, daca exista
    ///cu alte cuvinte poti avea doar val nodului deci elimini din arbore fii sai,
    ///sau valoarea nodului+ subarborii de cost pozitiv care pleaca din e
    ///dar mai intai iei nodurile pe rand si daca sunt frunze(au doar un vecin adica tatal) pui f[nod] pe 1
    for(i=1; i<=n; i++)
        if((cap[i+1]-cap[i])==1) f[i]=1;

    ///creezi vectorul de tati
    ///cu bfs
    viz2[1]=1;
    coada[prim]=1;
    bfs();

    vf=1;
    stiva[vf]=1;///pp ca nodul 1 este radacina, poti alege radacina orice  alt nod aleator
    viz[1]=1;///vizitezi nodul tau
    dfs();

    int32_t maxi=-inf;
    for(i=1; i<=n; i++)
        if(val[i]>maxi) maxi=val[i];
    f2<<maxi;
    return 0;
}