1. 程式人生 > >HDU 4717(樹形DP)

HDU 4717(樹形DP)

== cnblogs div code 刪除 splay 沒有 str std

由於內存的限制。所以盡量要少開數組。一開始用了數組記錄每個點的度數和每個點的兒子數,還有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;//統計兒子個數 } }
View Code

超內存的寫法。

#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; }

HDU 4717(樹形DP)