您的位置:首页 > 其它

将功补过(树形dp)

2016-05-12 20:49 288 查看
Description(

http://blog.csdn.net/liangzihao1/article/details/51364360

  作为间谍专家的ElvisHan受窃取X星球军事中心的秘密情报,他已经成功进入军事中心。但是很不幸的是,在他还没有找到任务需要情报的时候就被发现,这时他清楚他不可能完成任务了,不过还有机会将功补过,也就是得到一些不如任务情报有价值的其他情报,如果得到的情报的总价值大于等于任务情报价值,他也不会受到惩罚。很幸运的是他已经得到的军事中心的地图,情报都是隐藏在各个道路上的,但是他只有时间遍历一定数量的路(时间宝贵呀!还要逃跑。。)现在你做为他的助手,给你地图和每个道路情报价值,希望你分析出,看他能不能将功补过。

  军事中心是一个严格的二叉树,也就是说,如果有个点可以分道,一定是分出,也只分出2条道路,现在ElvisHan正处在第一个分道处,也就是说树的根结点处。每条道路上都有一个分数,就是这个道路上的情报价值。但是他只有时间走M条路,他的最终情报价值总和就是他所经过的路的情报价值总和(假设他到过的路一定可以把所有情报得到)希望你给出一个方案使得他可以尽量多地获取情报以便将功补过。

Input

共有N行:

第一行:3个数据:N,M,Q(N表示有多少个路口,包括分道和不分道的路口;M表示他可以有时间走的道路总数;Q表示他的任务情报的价值)

第2~N行:每行3个数据,Xi,Yi,Wi(X,Y表示第I条道路连接的2个路口,W表示这条道路上的情报价值分,注意,所有数据均在Lonint范围内)

Output

共包含2行:

第一行:输出TRUE/FALSE(注意大小写),表示他是否可以收集够任务情报价值

第二行:输出一个数据:

如果他可以完成任务,就输出他收集的情报总价值超过任务情报价值的部分。(正数)

如果不能完成任务,就输出一个数,表示他不能还差多少分才够任务情报价值。(负数)

SampleInput

【样例输入1】

3110

1210

138


【样例输入2】

9349

6215

7210

876

7915

1320

2110

438

357

SampleOutput

【样例输出1】

TRUE

0

样例说明:(该部分不必输出)

32

(8)\/(10)

1(选择1条路当然选1-2)


【样例输出2】

FALSE

-4

样例说明:

89

(6)\/(15)

6745

(15)\/(10)\(8)/(7)

23

(10)\/(20)

1(由于他最大可以取得的是[1->3]+[1->2]+[2->6]3条路径的价值,才45,所以不可能完成任务)


Hint

<数据规模>

对于30%的数据保证有N<=10

对于50%的数据保证有N<=40

对于全部的数据保证有N<=100

var

f,b:array[0..200,0..200]oflongint;

a:array[0..200,1..3]oflongint;

d:array[0..200]oflongint;

i,j,k,l:longint;

n,m,q:longint;

ans:longint;

proceduremake(v:longint);

var

i,j,k:longint;

begin

fori:=1tondo

begin

ifb[v,i]>0then

begin

a[v,1]:=i;

d[i]:=b[v,i]-1;

b[v,i]:=-1;b[i,v]:=-1;

make(i);

break;

end;

end;

fori:=1tondo

begin

ifb[v,i]>0then

begin

a[v,2]:=i;

d[i]:=b[v,i]-1;

b[v,i]:=-1;b[i,v]:=-1;

make(i);

break;

end;

end;

end;

proceduredfs(i,j:longint);

var

k:longint;

begin

ifj=0thenexit;

iff[i,j]<>0thenexit;

if(a[i,1]=0)and(a[i,2]=0)then

begin

f[i,j]:=d[i];

exit;

end;

fork:=0toj-1do

begin

dfs(a[i,1],k);

dfs(a[i,2],j-k-1);

iff[i,j]<f[a[i,1],k]+f[a[i,2],j-k-1]+d[i]

then

f[i,j]:=f[a[i,1],k]+f[a[i,2],j-k-1]+d[i];

end;

end;

begin

readln(n,m,q);

m:=m+1;

fori:=1ton-1do

begin

readln(j,k,l);

b[j,k]:=l+1;

b[k,j]:=l+1;

end;

fillchar(f,sizeof(f),0);

fillchar(a,sizeof(a),0);

make(1);

dfs(1,m);

ifq<=f[1,m]thenwriteln('TRUE')

elsewriteln('FALSE');

writeln(f[1,m]-q);

end.

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: