标签:ural 之间 guest state wan cal lines ica 理解
zoj 2342
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 9480 | Accepted: 5454 | 
Description
Input
Output
Sample Input
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
Sample Output
5
思路分析 :
给出 n 个人, 并且他们之间有一定的上下级关系, 在纸上画一画 会发现她更像一棵树, 但是写此类 dp 就需要你对递归有一个比较好的理解, 模拟建立一棵树, 找到树的根节点,采用 dfs 遍历一遍树,并且将走过的点做一个标记
状态转移方程 :
dp[node][1] += dp[i][0];
dp[node][0] += max(dp[i][0], dp[i][1]);
代码示例:
/*
 * Author:  ry 
 * Created Time:  2017/9/18 18:16:33
 * File Name: 1.cpp
 */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <time.h>
using namespace std;
const int mm = 1e6+5;
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define ll long long
int n;
int dp[6500][2];
int fa[6500];
bool vis[6500];
void dfs(int node){
    vis[node] = true;
    for(int i = 1; i <= n; i++){
        if (fa[i] == node && !vis[i]){
            dfs(i);
            dp[node][1] += dp[i][0];
            dp[node][0] += max(dp[i][0], dp[i][1]); 
        }
    }
}
int main() {
    int l, k;
    
    while(~scanf("%d", &n)){
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i++){
            scanf("%d", &dp[i][1]);
            dp[i][0] = 0;
        }
        int roof;
        for(int i = 1; i <= n; i++){
            scanf("%d%d", &l, &k);
            if (l+k == 0) break;
            fa[l] = k;
            roof = k;        
        }
        while(roof){
            roof = fa[roof];
        }
        dfs(roof);
        printf("%d\n", max(dp[roof][0], dp[roof][1]));
    }
    return 0;
}
标签:ural 之间 guest state wan cal lines ica 理解
原文地址:http://www.cnblogs.com/ccut-ry/p/7546159.html