Hdu1520-Anniversary party(트리 dp)(시작 문제)

전송문: Anniversary party
제목: 회사 내의 직원 관계표는 하나의 나무로 모든 직원은 하나의 권한을 가진다. 연회를 열 때 한 직원과 그의 직속 상사는 동시에 나타날 수 없다(즉 직접 인접한 노드는 동시에 선택할 수 없다). 최대 권한을 구한다.
사고방식: 트리 dp 입문 문제.
노드 1을 루트로 선택하고 각 노드 u와 해당 서브노드 v에 대해 다음을 수행합니다.
노드 u를 선택하면 노드 v를 선택할 수 없습니다.
dp[u][1] += dp[v][0]
노드 u를 선택하지 않으면 노드 v의 공헌도가 큰 것을 선택한다(제목의 요구는 동시에 선택할 수 없고 당연히 동시에 선택하지 않을 수 있다).
dp[u][0] += max(dp[v][0], dp[v][1])
tips: 제목의 또 다른 구덩이는 여러 그룹의 데이터가 명확하게 밝혀지지 않았다는 것이다.
 
AC 코드:
#include 
#include 
#include 
using namespace std;
const int maxn=6e3+7;
struct node{
    int to,nxt;
}e[maxn*2];
int a[maxn],tot,head[maxn],dp[maxn][2];
void add(int u,int v){
    e[tot].nxt=head[u];
    e[tot].to=v;
    head[u]=tot++;
    return;
}
void add_edge(int u,int v){
    add(u,v);
    add(v,u);
    return;
}
void dfs(int rt,int p){
    for(int i=head[rt];~i;i=e[i].nxt){
        int to=e[i].to;
        if(to==p) continue;
        dfs(to,rt);
        dp[rt][1]+=dp[to][0];
        dp[rt][0]+=max(dp[to][0],dp[to][1]);
    }
    dp[rt][1]+=a[rt];
    return;
}
int main(void){
    int n;
    while(~scanf("%d",&n)){
        tot=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            dp[i][0]=dp[i][1]=0;
            head[i]=-1;
        }
        int u,v;while(~scanf("%d%d",&u,&v)){
            if(!u&&!v) break;
            add_edge(u,v);
        }
        dfs(1,0);
        printf("%d
",max(dp[1][0],dp[1][1])); } return 0; }

좋은 웹페이지 즐겨찾기