Cod sursa(job #1506396)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 20 octombrie 2015 16:39:36
Problema Guvern Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.14 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <utility>
#include <tuple>
#include <cstdio>
using namespace std;
 
constexpr int unvisited = -1;

template <int dim>
class parsator{
	ifstream f;
	array<char, dim> buf;
	int poz;
	void refresh(){
		if(poz == dim){
			f.read(&buf[0], dim);
			poz = 0; } }
public:
	parsator(const char* const name): f(name), poz(dim){
		refresh(); }
	parsator<dim>& operator>>(int& x){
		while(!isdigit(buf[poz])){
			++poz;
			refresh(); }
		x = 0;
		while(isdigit(buf[poz])){
			x *= 10;
			x += buf[poz] - '0';
			++poz;
			refresh(); }
		return *this; } };
 
template <typename Set_t>
void dfs(const int cur, const int prev, const vector<vector<int> >& graf,
    const vector<int>& coop, vector<vector<int> >& fortat_de, Set_t& parinti,
    vector<pair<int, int> >& st_fin, int& poz_euler, vector<int>& best_subarb,
    vector<int>& best_upto_begin){
    /*
    cout << cur << " - ";
    for(const auto x : parinti){
        cout << x << ' '; }
    cout << endl;
    */
 
    if(!parinti.empty()){
        fortat_de[*parinti.lower_bound(cur)].push_back(cur); }
 
    st_fin[cur].first = poz_euler++;
 
    parinti.insert(cur);
    for(const auto next : graf[cur]){
        if(next != prev){
            dfs(next, cur, graf, coop, fortat_de, parinti, st_fin, poz_euler, best_subarb, best_upto_begin); } }
    parinti.erase(cur);
 
    st_fin[cur].second = poz_euler++;
    vector<pair<int, int>> evenimente;
    for(const auto x : fortat_de[cur]){
        evenimente.emplace_back(x, st_fin[x].first);
        evenimente.emplace_back(x, st_fin[x].second); }
    sort(begin(evenimente), end(evenimente),
        [](const pair<int, int>& a, const pair<int, int>& b){
            return a.second < b.second; });
    int best_here = 1;
    for(const auto x : evenimente){
        if(best_upto_begin[x.first] == unvisited){
            //echivalent cu x e un inceput
            best_upto_begin[x.first] = best_here; }
        else{
            best_here = max(best_upto_begin[x.first] + best_subarb[x.first],
                best_here); } }
    best_subarb[cur] = best_here; }
 
int main(){
    parsator<1000> f("guvern.in");
    ofstream g("guvern.out");
    int n;
    f >> n;
    vector<vector<int> > graf(n+1);
    vector<int> coop(n+1, 1000000001);
    for(int i = 0, a, b; i < n-1; ++i){
        f >> a >> b;
        graf[a].push_back(b);
        graf[b].push_back(a); }
    graf[0].push_back(1);
    graf[1].push_back(0);
    for(int i = 1; i <= n; ++i){
        f >> coop[i]; }
    vector<vector<int> > fortat_de(n+1);
    auto cmp = [&coop](const int x, const int y){
        return coop[x] < coop[y]; };
    set<int, decltype(cmp)> parinti(cmp);
    vector<pair<int, int> > st_fin(n+1);
    int poz_euler = 0;
    vector<int> best_subarb(n+1, unvisited), best_upto_begin(n+1, unvisited);
 
    dfs(0, -1, graf, coop, fortat_de, parinti, st_fin, poz_euler, best_subarb, best_upto_begin);
 
    /*
    for(int i = 0; i <= n; ++i){
        cout << i << " - ";
        for(const auto x : fortat_de[i]){
            cout << x << ' '; }
        cout << endl; }
    cout << endl;
    */
 
    g << best_subarb[0]-1;
    return 0; }