题目描述
【题目描述】
政府邀请了你在火车站开饭店,但不允许同时在两个相连接的火车站开。任意两个火车站有且只有一条路径,每个火车站最多有50个和它相连接的火车站。告诉你每个火车站的利润,问你可以获得的最大利润为多少?例如下图是火车站网络:
最佳投资方案是在1,2,5,6这 4个火车站开饭店可以获得利润为90。
输入输出格式
输入格式:
第一行输入整数N(≤100000),表示有N个火车站,分别用1,2,…,N来编号。接下来 N 行,每行一个整数表示每个站点的利润,接下来 N 一 1 行描述火车站网络,每行两个整数,表示相连接的两个站点。
输出格式:
输出一个整数表示可以获得的最大利润。
解题思路:
这是一道树形动态规划,dp[i][0]表示以i为根时,不选i的最大值,dp[i][1]为选i时的最大值;从根开始递归每一层,当选i时,不选它的子节点,则d[i][1]=d[i][1]+d[j][0];不选i时,可选可不选子节点(选最大),则d[i][0]=d[i][0]+max(d[j][0],d[j][1]),其中j为i的子节点。最终输出max(dp[rood][0],dp[rood][1]);
注意,数据量大,邻接表要把二维转一维
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int from,to,next,head;
}q[1100000];
int i,j,n,x,y,w[1100000],vis[1100000],d[1100000][2],s=0;
void dp(int r)
{
if(vis[r]) return;
else vis[r]=1;
int k,j;
k=q[r].head;
while(k!=0)
{
j=q[k].to;
if(!d[j][0]&&!d[j][1])
{
dp(j);
d[r][0]+=max(d[j][0],d[j][1]);
d[r][1]+=d[j][0];
}
k=q[k].next;
}
d[r][1]+=w[r];
}
int main()
{
cin>>n;
for(i=1;i<=n;i++) cin>>w[i];
for(i=1;i<n;i++)
{
cin>>x>>y;
q[++s].from=x;
q[s].to=y;
q[s].next=q[x].head;
q[x].head=s;
q[++s].from=y;
q[s].to=x;
q[s].next=q[y].head;
q[y].head=s;
}
dp(1);
cout<<max(d[1][0],d[1][1]);
return 0;
}