将功补过【树形DP】

Time Limit:10000MS Memory Limit:65536K
Total Submit:41 Accepted:28
Case Time Limit:1000MS


Description
  作为间谍专家的 E l v i s Elvis Elvis H a n Han Han受窃取 X X X星球军事中心的秘密情报,他已经成功进入军事中心。但是很不幸的是,在他还没有找到任务需要情报的时候就被发现,这时他清楚他不可能完成任务了,不过还有机会将功补过,也就是得到一些不如任务情报有价值的其他情报,如果得到的情报的总价值大于等于任务情报价值,他也不会受到惩罚。很幸运的是他已经得到的军事中心的地图,情报都是隐藏在各个道路上的,但是他只有时间遍历一定数量的路(时间宝贵呀!还要逃跑。。)现在你做为他的助手,给你地图和每个道路情报价值,希望你分析出,看他能不能将功补过。
  军事中心是一个严格的二叉树,也就是说,如果有个点可以分道,一定是分出,也只分出 2 2 2条道路,现在 E l v i s H a n Elvis Han ElvisHan正处在第一个分道处,也就是说树的根结点处。每条道路上都有一个分数,就是这个道路上的情报价值。但是他只有时间走 M M M条路,他的最终情报价值总和就是他所经过的路的情报价值总和(假设他到过的路一定可以把所有情报得到)希望你给出一个方案使得他可以尽量多地获取情报以便将功补过。


Input
共有N行:
第一行: 3 3 3个数据: N , M , Q N,M,Q NMQ N N N表示有多少个路口,包括分道和不分道的路口; M M M表示他可以有时间走的道路总数; Q Q Q表示他的任务情报的价值)
2   N 2~N 2 N行:每行 3 3 3个数据, X i , Y i , W i Xi,Yi,Wi Xi,Yi,Wi ( X , Y X,Y XY表示第I条道路连接的 2 2 2个路口, W W W表示这条道路上的情报价值分, 注意,所有数据均在 L o n i n t Lonint Lonint范围内)

Output
共包含 2 2 2行:
第一行:输出 T R U E / F A L S E TRUE/FALSE TRUE/FALSE(注意大小写),表示他是否可以收集够任务情报价值
第二行:输出一个数据:
如果他可以完成任务,就输出他收集的情报总价值超过任务情报价值的部分。(正数)
如果不能完成任务,就输出一个数,表示他不能还差多少分才够任务情报价值。(负数)


Sample Input
【样例输入1】
3 1 10
1 2 10
1 3 8

【样例输入2】
9 3 49
6 2 15
7 2 10
8 7 6
7 9 15
1 3 20
2 1 10
4 3 8
3 5 7

Sample Output
【样例输出1】
TRUE
0

【样例输出2】
FALSE
-4


<数据规模>
对于 30 30 30%的数据 保证有 N < = 10 N<=10 N<=10
对于 50 50 50%的数据 保证有 N < = 40 N<=40 N<=40
对于全部的数据 保证有 N < = 100 N<=100 N<=100


解题思路
这道题与 二叉苹果树 几乎一模一样!!一模一样!!一模一样!!


代码

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long n,m,q,x,y,z,a[110][110],s[110][110],c[110],v[110],f[110][110];
void dfs(int dep){
	v[dep]=1;
	for(int i=1;i<=c[dep];i++)
	{
		int son=s[dep][i];
		if(v[son]) continue;
		dfs(son);
		for(int j=m;j>0;j--)
		{
			for(int k=j-1;k>=0;k--)
			{
				f[dep][j]=max(f[dep][j],f[son][k]+f[dep][j-k-1]+a[dep][son]);
			}
		}
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n-1;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		a[x][y]=z;
		a[y][x]=z;
		s[x][++c[x]]=y;
		s[y][++c[y]]=x;
	}
	dfs(1);
	if(f[1][m]>=q)
		printf("TRUE\n%d",f[1][m]-q);
	else
		printf("FALSE\n%d",f[1][m]-q);
}

你可能感兴趣的:(树状DP)