sgu 143 Long live the Queen 简单树形dp

// sgu 143  Long live the Queen 简单树形dp
//
// 题意:在树上选一个连通字图,使得节点的权值之和最大
// f[i] 表示以该节点为根的字图权值之和的最大值
// 则有 f[i] = w[i] + sigma(max(0,f[j])) i是j的父节点
// 最后在所有的f中挑个最大值就是答案。。。。

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#define ceil(a,b) (((a)+(b)-1)/(b))
#define endl '\n'
#define gcd __gcd
#define highbit(x) (1ull<<(63-__builtin_clzll(x)))
#define popcount __builtin_popcountll
typedef long long ll;
using namespace std;
const int mod = 1000000007;
const long double pi = acos(-1.l);

template<class t> inline t lcm(const t& a, const t& b) { return a/gcd(a, b)*b; }
template<class t> inline t lowbit(const t& x) { return x&-x; }
template<class t> inline t maximize(t& a, const t& b) { return a=a<b?b:a; }
template<class t> inline t minimize(t& a, const t& b) { return a=a<b?a:b; }

const int maxn = 38900;
int w[maxn];
//int p[maxn];
vector<int> v[maxn];
bool vis[maxn];
int f[maxn];
int n;
struct node {
	int to;
	int next;
}edges[maxn];
int num;
int head[maxn/2];
void add_edge(int u,int v){
	edges[num].to = v;
	edges[num].next = head[u];
	head[u] = num++;

}
int dfs(int u,int fa){
	vis[u] = true;
	f[u] = w[u];
	for (int i=head[u];i!=-1;i=edges[i].next){
		int x = edges[i].to;

		if (!vis[x]){
			f[u] += max(0,dfs(x,u));
		}
	}

	return f[u];
}

void print(){
	for (int i=1;i<=n;i++)
		cout << f[i] << endl;
}
void init(){
	for (int i=1;i<=n;i++){
		scanf("%d",&w[i]);
	//	f[i] = w[i];
	}
	memset(head,-1,sizeof(head));
	num = 0;
	int a,b;
	for (int i=1;i<=n-1;i++){
		scanf("%d%d",&a,&b);
		add_edge(a,b);
		add_edge(b,a);
	}
	memset(vis,0,sizeof(vis));
	dfs(1,-1);
	int ans = f[1];
	for (int i=2;i<=n;i++)
		ans = max(ans,f[i]);
	printf("%d",ans);
	//print();
}

int main() {
	//freopen("g:\\code\\1.txt","r",stdin);
	scanf("%d",&n);
	init();
	return 0;
}

时间: 2024-11-05 23:35:54

sgu 143 Long live the Queen 简单树形dp的相关文章

SGU 143 Long Live the Queen (树形DP)

143. Long Live the Queen time limit per test: 0.25 sec. memory limit per test: 4096 KB The Queen of Byteland is very loved by her people. In order to show her their love, the Bytelanders have decided to conquer a new country which will be named accor

hdu 1520Anniversary party(简单树形dp)

Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4310    Accepted Submission(s): 1976 Problem Description There is going to be a party to celebrate the 80-th Anniversary of the

csu 2014 summer training day 3 简单树形dp

FZU 2157 题意:树上的节点可以打上0或1的标记,树的权值由两部分呢组成,点权和边权,有00.01.10.11四种组合的边权, 问最小权值和.以1节点为树根 分析:dp[x][0]表示x标记0后的最小的权值,dp[x][1]同理 那么每次可以计算dp[x][0],dp[x][1]: 例如dp[x][1]=min(dp[son][0]+lab[0][1]+val[1],dp[son][1]+bal[1][1]+val[1]); 具体看代码. 用bfs写的分层,深搜代码更简洁 1 #inclu

SGU 143 Long Live the Queen

题意: 输入:n代表n个城市,然后是n个数值,代表每个城市的盈利,接下来的n-1行输入a,b,代表城市ab间有一条路: 输出:连接几个城市所能达到的最大利润(每个城市间都能通) 本质上就是给出一棵无向树树和权值,求一个联通块的最大权值,典型的树形dp 1 #include <iostream> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 #define inf 0x3f3f3

[Luogu P1122]最大子树和 (简单树形DP)

题面 传送门:https://www.luogu.org/problemnew/show/P1122 Solution 这是一道简单的树形DP题. 首先,我们可以转换一下题面,可以发现,题目要求我们求出一颗树上的最大联通子图. 因为我们是在树上取的,实际上就是取一颗子树. 这个就是最基础的树形DP模型了. 我们可以设f[i]表示我们选的子图以i为根所能取的子树的最大值. 转移是: f[i] = beauty[i] + xigema(max(f[j],0)) (也就是一颗树的孩子所能取的子树,如果

HDU 3899 简单树形DP

题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道题目的做法是:先进行一次DFS,以每个节点为根,求出它下面节点到它的数量和. 再进行一次DFS,以每个节点为根,求出它下面节点到它的花费总和. source code: #pragma comment(linker, "/STACK:16777216") //for c++ Compile

UVALive - 2038 Strategic game (无向+记忆化+简单树形DP)

题目链接:https://vjudge.net/problem/UVALive-2038 题意:给定一棵树,选择尽量少的点,使得每个没有选中的结点至少和一个已经选中的结点相邻.输出最少需要选择的节点数.思路:经典的二分图最小顶点覆盖, 也是经典的树形 DP AC代码: #include<stdio.h> #include<string.h> #include<vector> #include<algorithm> using namespace std; c

SGU - 134 Centroid 无根树转有根树 + 树形DP

题目大意:给出一个无向图(树),要求你删除掉其中一个点,使剩下的点构成的子树中,节点数最大的那个值达到最小 解题思路:因为给出的是一个无根树,第一个想法就是先把它转成有根树,将1当成根 设sum[i]为以i为根节点的子树有多少个节点,那么sum[1] - sum[i]就相当于是排除了i的所有子节点的另一棵子树的节点总数了 设dp[i]为去掉了i节点后的剩余节点所构成的子树的节点的最大值 那么dp[i] = max(dp[i], sum[son]) son指的是和i相连的子节点 还有另一棵子树,就

poj2342 Anniversary party 简单树形dp

http://poj.org/problem?id=2342 Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4322   Accepted: 2459 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The Universi