现在的位置: 首页 > 综合 > 正文

poj 1192

2014年07月08日 ⁄ 综合 ⁄ 共 1194字 ⁄ 字号 评论关闭

http://blog.csdn.net/birdforever/article/details/5874502

题目中文。。。。但是描述得很复杂。。。不知道为啥要这样,

其实就是一个求无向树的所有子树和的最大值

树形dp

dp[i][0]表示以i为根,不包括i结点的子树获得最大权

dp[i][1]表示以i为根,包括i结点的子树获得的最大权

dp[i][0] = max(dp[k][0], dp[k][1]) k为i的所有孩子结点

dp[i][1] = i结点的权 + dp[k][1] 如果dp[k][1] > 0

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

struct node
{
    int u, next;
};

struct point
{
    int x, y, c;
};

const int maxn = 1010;

int dp[maxn][2], e, n, head[maxn];
bool visited[maxn];
node edge[maxn*10];
point points[maxn];

void addEdge(int u, int v);
void dfs(int u);
int main()
{
    e = 0;
    memset(head, -1, sizeof(head));
    memset(visited, 0, sizeof(visited));
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
        scanf("%d %d %d", &points[i].x, &points[i].y, &points[i].c);
    for(int i = 0; i < n; i++)
    {
        for(int j = i + 1; j < n; j++)
        {
            if((abs(points[i].x - points[j].x) + abs(points[i].y - points[j].y)) == 1)
                addEdge(i, j);
        }
    }
    dfs(0);
    printf("%d\n", max(dp[0][0], dp[0][1]));
    return 0;
}

void addEdge(int u, int v)
{
    edge[e].u = v;
    edge[e].next = head[u];
    head[u] = e++;
    
    edge[e].u = u;
    edge[e].next = head[v];
    head[v] = e++;
}

void dfs(int u)
{
    visited[u] = true;
    dp[u][0] = 0, dp[u][1] = points[u].c;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].u;
        if(!visited[v])
        {
            dfs(v);
            dp[u][0] = max(dp[u][0], max(dp[v][0], dp[v][1]));
            if(dp[v][1] > 0)
                dp[u][1] += dp[v][1];
        }
    }
}

 

抱歉!评论已关闭.