Cod sursa(job #615029)

Utilizator vladiiIonescu Vlad vladii Data 8 octombrie 2011 13:03:21
Problema Guvern Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.1 kb
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
using namespace std;
#define maxn 200010

int N, K;
int start[maxn], end[maxn], viz[maxn], cost[maxn], dyn[maxn], tmp[maxn];
vector<int> G[maxn], F[maxn];
vector<pair< pair<int, int>, int > > aux;
set<pair<int, int> > S, test;
set<pair<int, int> >::iterator it;

void DFS(int nod) {
    viz[nod] = 1;
    start[nod] = ++K;
    S.insert( make_pair(cost[nod], nod) );
    for(int i=0; i<G[nod].size(); i++) {
         if(!viz[ G[nod][i] ]) DFS( G[nod][i] );
    }
    end[nod] = ++K;
    S.erase( make_pair(cost[nod], nod) );

    if(nod) {
         it = S.lower_bound( make_pair(cost[nod], nod) );
         F[ (*it).second ].push_back(nod);
    }

    aux.clear();
    for(int i=0; i<F[nod].size(); i++) {
         aux.push_back( make_pair( make_pair(start[ F[nod][i] ], end[ F[nod][i] ]), dyn[ F[nod][i] ] ) );
    }

    test.clear();
    sort(aux.begin(), aux.end());

    int tot = (int)aux.size() - 1;

    dyn[nod] = 1;
    if(tot >= 0) {
         tmp[tot+1] = 0;
         tmp[tot] = aux[tot].second;
         test.insert( make_pair(aux[tot].first.first, tot) );

         for(int i=tot-1; i>=0; i--) {
              tmp[i] = tmp[i+1];
              it = test.lower_bound( make_pair(aux[i].first.second, 0) );
              if(it != test.end()) {
                   tmp[i] = max(tmp[i], aux[i].second + tmp[ (*it).second ]);
              }
              else {
                   tmp[i] = max(tmp[i], aux[i].second);
              }
              test.insert( make_pair(aux[i].first.first, i) );
         }

         dyn[nod] += tmp[0];
    }
}

int main() {
    FILE *f1=fopen("guvern.in", "r"), *f2=fopen("guvern.out", "w");
    int i, x, y;

    fscanf(f1, "%d\n", &N);
    for(i=1; i<N; i++) {
         fscanf(f1, "%d %d\n", &x, &y);
         G[x].push_back(y);
         G[y].push_back(x);
    }
    for(i=1; i<=N; i++) {
         fscanf(f1, "%d", &cost[i]);
    }

    G[0].push_back(1); G[1].push_back(0);
    cost[0] = 999999999;

    DFS(0);

    fprintf(f2, "%d\n", dyn[0] - 1);
    fclose(f1); fclose(f2);
    return 0;
}