您的位置:首页 > 其它

洛谷 P1352 没有上司的舞会

2018-02-26 15:10 260 查看
原题





这道题我非常神奇赖皮的用了拓扑,实际上这是一道树形dp,但是身为蒟蒻的我觉得拓扑可以写,结果真的让我水过了,哈哈哈
用一个二维数组模拟每个人参加或者不参加,从最底层的员工开始向上拓扑

代码//By Acer.mo
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
int happy[6005];
int ind[6005];
int fa[6005];
int dp[6005][2];//0|1表示参加或者不参加
int n,i,maxn=0,a,b,j;
void Topsort()
{
queue<int>q;
for(j=1;j<=n;j++)
if(ind[j]==0)
q.push(j);//将所有叶节点加入队列
while(!q.empty())//队列不为空
{
int u=q.front();//取出第一个叶子
q.pop();//移除
dp[u][1]+=happy[u];//如果参加,加上快乐值
maxn=max(max(dp[u][0],maxn),dp[u][1]);
//maxn在u元素参加||不参加中取最大
ind[fa[u]]--;//他的父节点的入读--
if(ind[fa[u]]==0)//如果当前叶子退出树
q.push(fa[u]); //加入队列
dp[fa[u]][0]=max(dp[fa[u]][0]+dp[u][0],dp[fa[u]][0]+dp[u][1]);
// 父节点不参加的最大快乐值等于当前节点参加与不参加取最大
if (dp[u][0]>=0)
dp[fa[u]][1]+=dp[u][0];
//如果当前节点不参加有快乐值,加到他的父节点参加的快乐值上
}
}
int main()
{
cin>>n;
for(i=1;i<=n;i++)
cin>>happy[i];//存储快乐值
while(cin>>a>>b)//循环读入关系
{
if(a==0&&b==0) break;
ind[b]++;//上司的入度++,因为边由叶指向根
fa[a]=b;//a的父节点为b;
}
Topsort();
cout<<maxn;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: