lightoj 1201 树形dp

来源:互联网 发布:算法基础打开算法之门 编辑:程序博客网 时间:2024/06/05 16:33

dp【0】【i】表示第i个不取得最大值

dp【1】【i】表示第i个取得最大值

注意各个点组成的可能是森林,要多次dfs

AC代码如下:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int MAX_N = 1100;struct Edge{    int to, next;};int head[MAX_N], tot;Edge edge[MAX_N*8];int N, M;int dp[2][MAX_N];bool mark[MAX_N];void add_edge( int a, int b ){    edge[tot].to = b;    edge[tot].next = head[a];    head[a] = tot++;    edge[tot].to = a;    edge[tot].next = head[b];    head[b] = tot++;}int DFS( int pre, int now_st, int pos ){    if( dp[now_st][pos] != -1 ){        return dp[now_st][pos];    }    mark[pos] = true;    dp[now_st][pos] = now_st;    for( int i = head[pos]; i != -1; i = edge[i].next ){        int to = edge[i].to;        if( to == pre ) continue;        if( now_st == 0 ){            dp[now_st][pos] += max( DFS( pos, 0, to ), DFS( pos, 1, to ) );        }else{            dp[now_st][pos] += DFS( pos, 0, to );        }    }    return dp[now_st][pos];}int main(){    int T, Case = 1;    scanf( "%d", &T );    while( T-- ){        scanf( "%d%d", &N, &M );        memset( head, -1, sizeof( head ) );        tot = 0;        for( int i = 0; i < M; i++ ){            int temp1, temp2;            scanf( "%d%d", &temp1, &temp2 );            add_edge( temp1, temp2);        }        memset( dp, -1, sizeof( dp ) );        memset( mark, false, sizeof( mark ) );        int ans = 0;        for( int i = 1; i <= N; i++ ){            if( !mark[i] ){                ans += max( DFS( -1, 0, i ), DFS( -1, 1, i ) );            }        }        printf( "Case %d: %d\n", Case++, ans );    }    return 0;}/*46 51 22 33 43 62 54 23 41 2anwser : 4, 2*/


0 0
原创粉丝点击