题目
政府邀请了你在火车站开饭店,但不允许同时在两个相连接的火车站开。任意两个火车站有且只有一条路径,每个火车站最多有50个和它相连接的火车站。
告诉你每个火车站的利润,问你可以获得的最大利润为多少。
最佳投资方案是在1,2,5,6这4个火车站开饭店可以获得利润为90
分析
树形dp,f[i]表示选择这个车站的最大利润,g[i]表示不选择这个车站的最大利润
状态转移方程:
$ f[i]+=g[i.y] g[i]=max(f[i.y],g[i.y])$
代码
#include <cstdio>
#include <algorithm>
#include <cctype>
using namespace std;
struct tree{
int x,y,next;
}e[200001];
bool check[100001]; int ls[100001],pay[100001],f[100001],g[100001],n,m;
int in(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
bool dp(int x){
if (check[x]) return 0;
check[x]=1;
int t=ls[x];
while (t){
if (dp(e[t].y)){
f[x]+=g[e[t].y];
g[x]+=max(f[e[t].y],g[e[t].y]);
}
t=e[t].next;
}
f[x]+=pay[x];
return 1;
}
int main(){
n=in(); for (int i=1;i<=n;i++) pay[i]=in(); m=(n-1)*2;
for (int i=1;i<m;i+=2){
e[i].x=e[i+1].y=in(); e[i].y=e[i+1].x=in();
e[i].next=ls[e[i].x]; ls[e[i].x]=i;
e[i+1].next=ls[e[i+1].x]; ls[e[i+1].x]=i+1;//;邻接表
}
dp(1);
printf("%d",max(f[1],g[1]));
return 0;
}