UVa Placing Lampposts 树型DP

大致思路和大白书上的相同,不过感觉书上的决策部分讲解的并不是非常清楚,因此我在这里讲解一下我的决策思路。

首先,d(i,j)表示根节点为i的子树,当它的父节点为j(j=0或1)时的x的最小值(x的含义书上有讲解),要将该子树根节点和父节点相连的边的情况计算在内。接下来遍历森林中的每一棵树,对于每一棵树的根节点进行特别的处理,然后就对该树进行深度优先搜索dfs(i)。

对于d[i][0]的情况,因为当前子树根节点i的父节点为0,所以该子树根节点的状态必为1,则d[i][0]=sum{d[k][1]|k为i的子节点}+M+1。然而,对于d[i][1]则需要分两种情况进行讨论:当i为1时,d1=sum{d[k][1]|k为i的子节点}+M,当i为0时,d0=sum{d[k][0]|k为i的子节点}+1,则d[i][1]=min(d0,d1)。最后每棵树的根节点都按照自身为1和自身为0,分别加上对于的sum{d[k][j]|k为对应根节点的子节点}即可。详细解答见代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 1000+5
#define M   2000
using namespace std;

int T,n,m,x;
int G[MAX][MAX],vis[MAX],d[MAX][2];
void dfs(int);

int main()
{
    cin>>T;
    while(T--){
        cin>>n>>m;
        memset(G,0,sizeof(G));
        x=0;

        int a,b;
        for(int i=0;i<m;++i){
            cin>>a>>b;
            G[a][b]=G[b][a]=1;
        }

        memset(vis,0,sizeof(vis));
        memset(d,0,sizeof(d));

        for(int i=0;i<n;++i) if(!vis[i]){
            vis[i]=1;
            int d0=0,d1=0;

            for(int j=0;j<n;++j) if(G[i][j]){
                dfs(j);
                d0+=d[j][0];
                d1+=d[j][1];
            }
            d1+=M;
            x+=min(d0,d1);

        }
        cout<<x/M<<" "<<m-x%M<<" "<<x%M<<endl;
    }

    return 0;
}

void dfs(int root)
{
    int leaf=1,d0=0,d1=0;
    vis[root]=1;

    for(int i=0;i<n;++i) if(!vis[i]&&G[root][i]){
        leaf=0;
        dfs(i);
        d[root][0]+=d[i][1];
        d0+=d[i][0];
        d1+=d[i][1];
    }
    d[root][0]+=M+1;
    d[root][1]=min(d1+M,d0+1);

    if(leaf){//叶子节点特殊处理
        d[root][0]=M+1;
        d[root][1]=1;
    }

    return;
}
时间: 2024-10-21 00:58:27

UVa Placing Lampposts 树型DP的相关文章

HDU1561 The more, The Better(树型DP)

题目是有n个存有宝藏的城堡,攻克任何一个城堡都需要先攻克0个或其他1个城堡,问攻克m个城堡最多能得到多少宝藏. 题目给的城堡形成一个森林,添加一个超级根把森林连在一起就是树了,那么就考虑用树型DP: dp[u][m]表示以u结点为根的子树攻克m个结点的最大价值 但是这样转移太难了,根是从每个孩子通过各自分配若干的城堡去攻克转移的,一个排列组合数,阶乘,是指数级的时间复杂度! 看了题解,原来这是依赖背包,没看背包九讲..不过网上的博客似乎没说清楚,事实上这个状态应该是三个维度来表示: dp[u][

POJ3659 Cell Phone Network(树上最小支配集:树型DP)

题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. 树上的每个结点作为其子树的根可以有三个状态: 不属于支配集且还没被支配 不属于支配集但被其孩子支配 属于支配集 那么就是用dp[u][1\2\3]来表示动归的状态. 123转移该怎么转移就怎么转移..最后的结果就是min(dp[root][2],dp[root][3]). 要注意的是对于有些结点前2

HDU_1561_The more, The Better_树型dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7031    Accepted Submission(s): 4121 Problem Description ACboy很喜欢玩一种战略游戏,

HDU_1520_Anniversary party_树型dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8233    Accepted Submission(s): 3574 Problem Description There is going to b

二叉苹果树(树型DP+背包)

二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树: 2   5 \  / 3  4 \  / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 程序名:apple 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=

HDU_1011_Starship Troopers_树型dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16276    Accepted Submission(s): 4335 Problem Description You, the leader o

【HDOJ 5834】Magic boy Bi Luo with his excited tree(树型DP)

[HDOJ 5834]Magic boy Bi Luo with his excited tree(树型DP) Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Bi Luo is a magic boy, he also has a migic tree,

【POJ 2486】 Apple Tree(树型dp)

[POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8981   Accepted: 2990 Description Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each

[HAOI2010][BZOJ2427] 软件安装|tarjan|树型dp

2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 463  Solved: 194[Submit][Status][Discuss] Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(