洛谷 P1352 没有上司的舞会

原题

这道题我非常神奇赖皮的用了拓扑,实际上这是一道树形dp,但是身为蒟蒻的我觉得拓扑可以写,结果真的让我水过了,哈哈哈

用一个二维数组模拟每个人参加或者不参加,从最底层的员工开始向上拓扑

代码

//By Acer.mo
#include
#include
#include
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()
{
    queueq;
    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<


你可能感兴趣的:(图论-拓扑排序)