您的位置:首页 > 其它

POJ1155:TELE(树形DP)

2013-08-11 23:55 435 查看
Description
ATV-networkplanstobroadcastanimportantfootballmatch.Theirnetworkoftransmittersanduserscanberepresentedasatree.Therootofthetreeisatransmitterthatemitsthefootballmatch,theleavesofthetreeare
thepotentialusersandotherverticesinthetreearerelays(transmitters).

Thepriceoftransmissionofasignalfromonetransmittertoanotherortotheuserisgiven.Apriceoftheentirebroadcastisthesumofpricesofallindividualsignaltransmissions.

EveryuserisreadytopayacertainamountofmoneytowatchthematchandtheTV-networkthendecideswhetherornottoprovidetheuserwiththesignal.

WriteaprogramthatwillfindthemaximalnumberofusersabletowatchthematchsothattheTV-network'sdoesn'tlosemoneyfrombroadcastingthematch.
Input
ThefirstlineoftheinputfilecontainstwointegersNandM,2<=N<=3000,1<=M<=N-1,thenumberofverticesinthetreeandthenumberofpotentialusers.

Therootofthetreeismarkedwiththenumber1,whileothertransmittersarenumbered2toN-MandpotentialusersarenumberedN-M+1toN.

ThefollowingN-Mlinescontaindataaboutthetransmittersinthefollowingform:

KA1C1A2C2...AKCK

MeansthatatransmittertransmitsthesignaltoKtransmittersorusers,everyoneofthemdescribedbythepairofnumbersAandC,thetransmitteroruser'snumberandthecostoftransmittingthesignaltothem.

Thelastlinecontainsthedataaboutusers,containingMintegersrepresentingrespectivelythepriceeveryoneofthemiswillingtopaytowatchthematch.
Output
Thefirstandtheonlylineoftheoutputfileshouldcontainthemaximalnumberofusersdescribedintheabovetext.
SampleInput
96
3223293
24252
3627282
433311

SampleOutput
5


题意:电视台发送信号给很多用户,每个用户有愿意出的钱,电视台经过的路线都有一定费用,求电视台不损失的情况下最多给多少用户发送信号。

思路:树状dp。由于求的是最多多少用户,那么我们可以把用户个数当成一个状态。dp[i][j]代表i节点为根节点的子树j个用户的时候最大剩余费用。   则dp[i][j]=max(dp[i][j],dp[i][k]+dp[son][j-k]-w[i][son]);
   注意两点,第一点是上面式子中的dp[i][k]必须先用一个tem[MAX]数组提取出来,因为在计算的过程中会相互影响。第二点是价值可能是负值,所以dp初始化的时候要初始化为负的最大值。



#include<stdio.h>
#include<string.h>
#include<algorithm>
usingnamespacestd;

structnode
{
intnow,val,next;
}tree[9005];

intn,m,len=0;
intnum[3005],head[3005],dp[3005][3005],tem[3005];

voidadd(inti,intx,inty)
{
tree[len].now=x;
tree[len].val=y;
tree[len].next=head[i];
head[i]=len++;
}

voiddfs(introot)
{
inti,j,k,p;
for(i=head[root];i!=-1;i=tree[i].next)
{
p=tree[i].now;
dfs(p);
for(j=0;j<=num[root];j++)
tem[j]=dp[root][j];
for(j=0;j<=num[root];j++)
{
for(k=1;k<=num[p];k++)
dp[root][k+j]=max(dp[root][j+k],tem[j]+dp[p][k]-tree[i].val);
}
num[root]+=num[p];
}
}

intmain()
{
inti,j,k,a,b;
while(~scanf("%d%d",&n,&m))
{
memset(head,-1,sizeof(head));
for(i=1;i<=n-m;i++)
{
scanf("%d",&k);
num[i]=0;
for(j=0;j<k;j++)
{
scanf("%d%d",&a,&b);
add(i,a,b);
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
dp[i][j]=-10000000;
}
for(i=n-m+1;i<=n;i++)
{
num[i]=1;
scanf("%d",&dp[i][1]);
}
dfs(1);
for(i=m;i>=0;i--)
{
if(dp[1][i]>=0)
{
printf("%d\n",i);
break;
}
}
}

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