来源:JZOJ #454
题目描述
政府邀请了你在火车站开饭店,但不允许同时在两个相连接的火车站开。
任意两个火车站有且只有一条路径,每个火车站最多有 个和它相连接的火车站。
告诉你每个火车站的利润,问你可以获得的最大利润为多少。
例如下图是火车站网络:
最佳投资方案是在
这
个火车站开饭店可以获得利润为
解题思路
- 我们用 表示在第 个点开饭店可获得的最大利润;
- 表示第 个点不开饭店可获得的最大利润;
- 可得状态转移方程:
- ( 为 的子节点)
- ( 为 的子节点)
- 用邻接表存储, ,
代码君
#include <bits/stdc++.h>
using namespace std;
int vis[200010],f[200010],v[200010],g[200010],linkk[200010];
int n,t=0;
struct node
{
int y,next;
}e[200010];
void insert(int x,int y) //邻接表存储
{
e[++t].y=y;
e[t].next=linkk[x]; linkk[x]=t;
}
void dfs(int x)
{
f[x]=v[x];
for (int i=linkk[x];i;i=e[i].next)
{
int y=e[i].y;
if (!vis[y])
{
vis[y]=1; //标记
dfs(y);
f[x]+=g[y]; //状态转移
g[x]+=max(f[y],g[y]);
}
}
}
int main()
{
freopen("profit.in","r",stdin);
freopen("profit.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&v[i]);
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d %d",&x,&y);
insert(x,y); //邻接表插入
insert(y,x);
}
memset(f,0,sizeof(g));
memset(g,0,sizeof(f));
memset(vis,0,sizeof(vis));
vis[1]=1;
dfs(1);
printf("%d",max(f[1],g[1]));
return 0;
}