Pagini recente » Cod sursa (job #1875152) | Cod sursa (job #19690) | Cod sursa (job #1208075) | Cod sursa (job #2413443) | Cod sursa (job #1826960)
#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;
}