HDU 4717(树形DP)

由于内存的限制。所以尽量要少开数组。一开始用了数组记录每个点的度数和每个点的儿子数,还有vis记录这个点是否处理过。然后超内存了。

实际上儿子数没有必要存下来,只是每次遍历自身的时候会用到,然后是否用过可以是每次dfs的返回值。

void dfs(int u,int f)  
{  
    for(int i=head[u];~i;i=edge[i].next)  
    {  
        int v=edge[i].v;  
        if(v==f)continue;  
        fa[v]=u;  
        dfs(v,u);  
        if(son[v]>=2)  
        {  
            num+=degree[v]-2;//删除v的n-1个儿子以及<u,v>  
            vis[v]=1;//删除v节点  
            degree[fa[v]]--;//让其父节点的度-1  
        }  
        if(!vis[v])  
        son[u]+=1;//统计儿子个数  
    }  
}  

超内存的写法。

#include <cstdio>
#include <cstring>
#include <iostream>

#define Max 1000001
#define MAXN 1001009
#define MOD 1000000007
#define rin freopen("in.txt","r",stdin)
#define rout freopen("1.out","w",stdout)
#define Del(a,b) memset(a,b,sizeof(a))
typedef long long LL;
using namespace std;
const int N = 1000005;
int T;
struct Node {
    int next;
    int to;
} e[N*2];
int tot, ans;
int head[N];
void Init(int n) {

    Del(head, -1);
    ans=0;
    tot = 0;
}
void addedge(int from, int to) {
    e[tot].to = to;
    e[tot].next = head[from];
    head[from] = tot++;
}
int dfs(int u, int father) {
    int son=0;
    for (int i = head[u]; i != -1; i = e[i].next) {
        int v=e[i].to;
        if(v==father)
            continue;
        son+=dfs(v,u);
    }
    if(son>=2){
        ans+=son-1;
        if(u==1)
            ans--;
        return 0;
    }
    else
        return 1;
}
int main() {
    rin;
    int n,T;
    while (cin >> T) {
        while (T--) {
            scanf("%d", &n);
            Init(n);
            for (int i = 1; i < n; i++) {
                int x, y;
                scanf("%d%d", &x, &y);
                addedge(y, x);
                addedge(x, y);

            }
            dfs(1,-1);
            printf("%d\n",ans*2+1);
        }
    }
    return 0;
}
时间: 2024-11-09 12:59:42

HDU 4717(树形DP)的相关文章

hdu 4123 树形DP+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=4123 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses,

hdu 1250 树形DP

Anniversary party Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-27) Description There is going to be a party to celebrate the 80-th Anniversary of the Ural St

hdu 4276(树形dp)

题意:带权树上有起点终点每个点上有宝藏,一个人只有T分钟要从起点到重点,问你最多能收集多少宝藏. 思路:树形dp,首先判断能不能走到终点,然后把路径上的边权变为0时间减去所有边权.dp[v][j]表示从v出发回到v话费j分钟最多能收集到的宝藏. dp[v][j] = max(dp[v][j], dp[x][k] + dp[v][j-k-2*val]); 被G++卡了好长时间,换成c++就过了. 代码如下: 1 #include <stdio.h> 2 #include <string.h

hdu 5148 树形dp+分组背包问题

http://acm.hdu.edu.cn/showproblem.php?pid=5148 Problem Description Long long ago,there is a knight called JayYe.He lives in a small country.This country is made up of n cities connected by n-1 roads(that means it's a tree).The king wants to reward Ja

HDU 1520 树形dp裸题

1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using nam

hdu 3586 树形dp+二分

题目大意:给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵 树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限limit,问切断所 有前线与司令部联系所花费的总费用少于m时的最小limit.1<=n<=1000,1<=m<=100万 题目要问的是最小的最大限制,必然二分答案 然后对于每一个值,树形DP判定是否可行 dp[i]表示要切断以i为根的其它所有子树的最小代价. 其中设定叶子结点的代价为无穷大

HDU 1561 树形DP入门

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6011    Accepted Submission(s): 3555 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物

hdu 1561 树形dp

又一道树形dp,发现其实树形dp长得都挺像的. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = -9999999; 7 const int N = 201; 8 int dp[N][N]; 9 int head[N]; 10 int value[N]; 11 int n, m, e; 12 13 void i

hdu 1011 树形dp+背包

题意:有n个房间结构可看成一棵树,有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个房间有一定的敌人,每个士兵可以对抗20个敌人,士兵在某个房间对抗敌人使无法走开,同时有一个价值,问你花费这m个士兵可以得到的最大价值是多少 分析:树形dp,对于点u,dp[u][j]表示以u为根的树消耗j个士兵得到的最大值,dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[son][k]+val[u]) 注意是无向图,vis位置不能随便放,且注意dp不能直接+val,因为这样根节点就加不

HDU 4340 树形DP

[题意]: 给你一张无向图,无向图上每个点代表一个城市,有两个值Va,Vb,分别代表a,b占领该城市所需要消耗的时间,而且a或b去占领它们已经占领的城市的相领城市所需的花费为标准的一般.问最少需要花费多少钱. [知识点]: 树形DP [题解]:dp[u][i][0]:代表以u为根的子树中没有一个点为颜色i绘画开始点所需的最小花费,即字数中画有i颜色的点的代价都为原来的一般dp[u][i][1]:代表以u为根的子树中有一个点为颜色i绘画开始点所需的最小花费u的子树中涂i色的点中有一个点为其本身的代