加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

hdu-5834 Magic boy Bi Luo with his excited tree 树形dp

发布时间:2020-12-14 05:01:43 所属栏目:大数据 来源:网络整理
导读:http://acm.hdu.edu.cn/showproblem.php?pid=5834 神级烦的一个树形dp dp1【0】【x】代表从x结点向下走并且回到x结点的最大值 dp1【1】【x】代表从x结点向下走,并且不回到x结点的最大值(去向某一个子树分支,通过index【x】记录) dp1【1】【x】代表从x结

http://acm.hdu.edu.cn/showproblem.php?pid=5834

神级烦的一个树形dp

dp1【0】【x】代表从x结点向下走并且回到x结点的最大值

dp1【1】【x】代表从x结点向下走,并且不回到x结点的最大值(去向某一个子树分支,通过index【x】记录)

dp1【1】【x】代表从x结点向下走,并且不回到x结点的第二大值

dp2【0】【x】代表从x结点向父节点走,并且回来的最大值

dp2【1】【x】代表从x结点向父节点走,并且不回来的最大值



dp1【0】,每个子结点走下去在回来
dp1【1】选一个子结点走下去不回来,其余走下去回来
dp1【2】同上

dp2【0】走到父节点fa之后,去向父父结点再回来,再去向父节点的非自己子节点(兄弟结点)再回来
dp2【1】走到父节点fa之后,去向父父结点再回来,再去向父节点的非自己子节点(兄弟结点)不回来,选一个兄弟结点走下去(这里就会用到dp1【2】,当index【fa】等于自己时)
或者去向父节点的非自己子节点(兄弟结点)回来,再去向父父结点不回来


很啰嗦,很烦,wa了很多发QAQ

带了几个调试时举得样例

#include<bits/stdc++.h>
using namespace std;
const int maxn=200005;
const int inf=0x3f3f3f3f;
long long dp1[3][maxn];
long long index[maxn];
long long dp2[2][maxn];
long long ans[maxn];
struct node
{
    int ne,cost;
};
int n;
int v[maxn];
vector<node>w[maxn];

void dfs1(int x,int fa)
{
	dp1[0][x]=v[x];
    for(int i=0;i<w[x].size();i++)
    {
        node ne=w[x][i];
        if(ne.ne==fa)
            continue;
        dfs1(ne.ne,x);
        if(dp1[0][ne.ne]-2*ne.cost>0)
        dp1[0][x]+=dp1[0][ne.ne]-2*ne.cost;
    }
    dp1[2][x]=dp1[1][x]=dp1[0][x];
    for(int i=0;i<w[x].size();i++)
    {
    	node ne=w[x][i];
    	if(ne.ne==fa)
    		continue;
    	int now=dp1[0][x]-max(dp1[0][ne.ne]-2*ne.cost,0ll)+dp1[1][ne.ne]-ne.cost;
    	if(now>=dp1[1][x])
    	{
    		dp1[2][x]=dp1[1][x];
    		index[x]=ne.ne;
    		dp1[1][x]=now;
		}
		else if(now>=dp1[2][x])
		{
			dp1[2][x]=now;
		}
	}
}
void dfs2(int x,int fa)
{
    int i,k;
    for(i=0;i<w[x].size();i++)
    {
        node ne=w[x][i];
        if(ne.ne==fa)
            continue;
        int self=dp1[0][ne.ne]-2*ne.cost;
        if(self<0)
        self=0;
    	dp2[0][ne.ne]=max(dp2[0][ne.ne],dp1[0][x]-self+dp2[0][x]-2*ne.cost);
		if(ne.ne==index[x])
		{
			dp2[1][ne.ne]=max(dp2[1][ne.ne],dp2[0][x]-ne.cost+dp1[2][x]-self);
		}
		else
		{
			dp2[1][ne.ne]=max(dp2[1][ne.ne],dp2[0][x]-ne.cost+dp1[1][x]-self);
		}
		dp2[1][ne.ne]=max(dp2[1][ne.ne],dp1[0][x]-self+dp2[1][x]-ne.cost);
		dfs2(ne.ne,x);
	}
}

int main()
{
    int tca=1,T,i;
    cin>>T;
    while(T--)
    {
      	scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&v[i]);
        }
        int u1,u2,c;
        for(i=1;i<n;i++)
        {
            scanf("%d %d %d",&u1,&u2,&c);
            node tt;
            tt.ne=u2;
            tt.cost=c;
            w[u1].push_back(tt);
            tt.ne=u1;
            w[u2].push_back(tt);
        }
        printf("Case #%d:n",tca++);
        for(i=0;i<=n;i++)
        dp1[0][i]=dp1[1][i]=dp1[2][i]=dp2[0][i]=dp2[1][i]=0,index[i]=-1;

  /*      node tt;
        tt.ne=1;
        v[0]=0;
        tt.cost=0;
        w[0].push_back(tt);
		dfs1(0,0);
        dfs2(0,0);*/
        dfs1(1,0);
        dfs2(1,0);
        for(i=1;i<=n;i++)
        {
   //         cout<<dp1[0][i]<<" "<<dp1[1][i]<<" "<<dp2[0][i]<<" "<<dp2[1][i]<<endl;
            printf("%dn",max(dp1[0][i]+dp2[1][i],dp1[1][i]+dp2[0][i]));
        }
        for(i=0;i<=n;i++)
        w[i].clear();
    }
    return 0;
}
/*

5
2 6 3 3 4
1 2 5
1 3 1
1 4 4
1 5 2


5
3 3 3 3 3
1 2 1
1 3 1
1 4 1
1 5 1


10
2 2 2 2 2 2 2 4 4 4
1 2 1
2 3 1
2 4 1
2 5 1
2 6 1
1 7 5
7 8 1
7 9 1
7 10 1

*/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读