#4033. 맛있는 QQ(eat)

제목 설명
어느 날, 맛있는 QQ는 화성인에 의해 영문도 모른 채 수형국의 수도 루트로 전송되었다. 그 이름처럼 수형국은 바로 나무이다. 모두 n개 도시이고 n-1개의 길이 연결되어 도시와 도시 사이가 연결된다.
놀랍게도 QQ는 어떤 방법을 써야 할지 몰라서 수형국 각 도시의 음식 종류(임의의 두 가지 음식이 모두 다른 종류라고 볼 수 있다)를 알게 되었다. 그래서 그는 수형국을 놀면서 다양한 음식을 맛보고 싶었다. QQ는 한 도시 s에서 이웃 도시 t까지 갔다. 그리고 도시 t에만 그가 먹지 않은 음식이 존재할 때 그는 도시 t에 도착한 후에 바로 그 음식을 맛보았다.이 도시의 다른 간식은 맛보지 못한다
그러면 맛있는 QQ를 위해 노선을 설계해서 화성인들이 그를 집에 데려다 줄 수 있도록 하세요.
입력 형식
첫 번째 줄의 개수 n은 수형국의 도시 수를 나타낸다
두 번째 줄 n개수는 각 도시의 간식 종류를 나타낸다
아래 n-1줄, 줄당 2개수 a, b는 도시 a, b를 연결하는 길이 있음을 나타낸다.
다음 줄의 루트는 수형국의 수도를 나타낸다
출력 형식
한 숫자는 QQ가 가장 많이 먹을 수 있는 몇 가지 간식을 나타낸다
샘플 입력
5 2 1 1 1 1 1 2 2 3 1 4 4 5 1
샘플 출력
4
데이터 범위 및 프롬프트
【우정 힌트】 처음에 수도로 전송되었을 때 QQ는 수도의 간식을 맛보지 않습니다. 마지막으로 수도 루트 샘플 코스로 돌아가 start>1>2(+)>1(+)>4(+)>1(+)>end
[데이터 약정] t를 max(도시별 간식 종류} 30%로 설정하면 n≤5, t≤5 60% 데이터 만족 n≤30, t≤30 100% 데이터 만족 n≤100000, 0≤t≤2^31
출처
장군Noip2014 시뮬레이션 1문제: 트리 DP
#include
#include
#include
#include
#include
#define N 100005
using namespace std;
long long f[N],res[N],up[N];
int n,root,head[N],ver[N<<1],nex[N<<1],tot,fa[N],cnt[N];
struct node
{
	int ff;
}temp[N];
bool cmp(node a,node b){
	return a.ff>b.ff;
}
inline void add(int x,int y){
	nex[++tot]=head[x];
	head[x]=tot;
	ver[tot]=y;
}
void tree_dfs(int x){
	up[x]-=1;
	if(x!=root&&up[x]>=0)f[x]+=1;
	for(int i=head[x];i;i=nex[i]){
		int y=ver[i];
		if(fa[x]==y)continue;
		fa[y]=x;
		tree_dfs(y);
	}long long now=0;
	for(int i=head[x];i;i=nex[i]){
		int y=ver[i];
		if(fa[x]==y)continue;
		temp[++cnt[x]].ff=f[y];
		now=now+res[y];
	}
	sort(temp+1,temp+1+cnt[x],cmp);
	for(int i=1;i<=cnt[x];++i){
		if(up[x]<=0)break;
		if(temp[i].ff<=0)break;
		f[x]=f[x]+temp[i].ff+1;up[x]-=1;
	}
	f[x]+=2*max((long long)0,min(now,up[x]));
	res[x]=max((long long)0,up[x]-now);
	//cout<
}
int main()
{
	//freopen("eat.in","r",stdin);
	//freopen("eat.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;++i)scanf("%lld",&up[i]);
	for(int i=1;i<n;++i){
		int x,y;scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	cin>>root;
	fa[root]=-1;up[root]+=1;
	tree_dfs(root);
	//fa[4]=1;
	//tree_dfs(4);
//	for(int i=1;i<=n;i++)cout<
	cout<<f[root]<<endl;
	return 0;
}
/*
4
0 3 2 0 
2 3
1 2
4 1
2
*/
	

좋은 웹페이지 즐겨찾기