Cod sursa(job #586161)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 30 aprilie 2011 13:55:03
Problema Guvern Scor 0
Compilator cpp Status done
Runda Algoritmiada 2011, Runda Finală, Clasele 10-12 Marime 2.04 kb
#include<stdio.h>
#include<vector>

using namespace std;

#define maxN 200005

FILE*f=fopen("guvern.in","r");
FILE*g=fopen("guvern.out","w");

vector<int>A[maxN];

int n,i,Niv[maxN],Viz[maxN],Coop[maxN],Nec[maxN],x,y,Min,nodmin,X[maxN],Fr[maxN],k,Nr,maxsub;
int maxx;

void dfs1(int nod,int niv){
	Niv[nod] = niv;
	Viz[nod] = 1;
	int nrsub = 0;
	for ( int i = 0 ; i < A[nod].size () ; ++i ){
		if ( !Viz[A[nod][i]] ){
			++nrsub;
			dfs1(A[nod][i],niv+1);
		}
	}
	if ( !nrsub ){
		Fr[++k] = nod;
	}
}

void dfs2(int nod){
	
	if ( nod != i ){
		if ( Coop[nod] < Min && Coop[nod] >= Coop[i] )
			Min = Coop[nod],nodmin = nod;
	}
	
	for ( int i = 0 ; i < A[nod].size() ; ++i ){
		if ( Niv[A[nod][i]] < Niv[nod] ){
			dfs2(A[nod][i]);
		}
	}
	
}

void dfs3(int nod ){
	
	maxsub = maxsub > Coop[nod] ? maxsub : Coop[nod];
	
	for ( int i = 0 ; i < A[nod].size () ; ++i ){
		if ( Niv[A[nod][i]] > Niv[nod] )
			dfs3(A[nod][i]);
	}
	
}

inline int maxsubarb ( int nod ){
	maxsub = 0;
	
	dfs3(nod);
	
	return maxsub;
}

bool solutie () {
	
	int i;
	
	for ( i = 1 ; i <= n ; ++i ){
		if ( Nec[i] != -1 && !X[Nec[i]] && X[i] )
			return 0;
	}
	
	for ( i = 1 ; i <= n ; ++i ){
		if ( !X[i] ) continue;
		if ( maxsubarb(i) > Coop[i] )
			return 0;
	}
	
	
	return 1;
}


void back( int niv ){
	if ( niv == n + 1 ){
		
		if ( Nr > maxx ){
			if ( solutie() ){
				maxx = Nr;
			}
		}
		
		return ;
	}
	for ( int i = 0 ; i <= 1 ; ++i ){
		X[niv] = i;
		if ( i )	++Nr;
		back(niv+1);
		if ( i )	--Nr;
	}
}

int main () {
	
	fscanf(f,"%d",&n);
	
	for ( i = 1 ; i < n ; ++i ){
		fscanf ( f, "%d %d",&x,&y) ;
		A[x].push_back(y);
		A[y].push_back(x);
	}
	for ( i = 1 ; i <= n ; ++i ){
		fscanf(f,"%d",&Coop[i]);
	}
	
	dfs1(1,0); for ( i = 1 ; i <= n ; ++i ){ Viz[i] = 0; }
	
	Nec[1] = -1;
	for ( i = 2 ; i <= n ; ++i ){
		Min = 1 << 29;
		dfs2(i);
		Nec[i] = Min == 1 << 29 ? -1 : nodmin;
	}
	
	back(1);
	
	fprintf(g,"%d\n",maxx);
	
	fclose(f);
	fclose(g);
	
	return 0;
}