POJ 1655 Balancing Act 焦点树

标题效果:鉴于一棵树。除去一个点之后,这棵树将成为一些中国联通的块。之后该点通过寻求取消最低形成块的最大数目。

思维:树DP思维。通过为每个子树尺寸的根节点深搜索确定。之后该节点然后除去,,还有剩下的部分。求一下这些块中数目的最大值。就是去掉这个点时的ans。然后更新总的ans。

这个题事实上就是树的重心。

CODE:

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

int cases;
int points;
int head[MAX],total;
int next[MAX << 1],aim[MAX << 1];

int p_ans,ans;

inline void Initialize();
inline void Add(int x,int y);
int DFS(int x,int last);

int main()
{
	for(cin >> cases;cases; --cases) {
		scanf("%d",&points);
		Initialize();
		for(int x,y,i = 1;i < points; ++i) {
			scanf("%d%d",&x,&y);
			Add(x,y),Add(y,x);
		}
		DFS(1,0);
		printf("%d %d\n",p_ans,ans);
	}
	return 0;
}

inline void Initialize()
{
	ans = 0x7f7f7f7f,total = 0;
	memset(head,0,sizeof(head));
}

inline void Add(int x,int y)
{
	next[++total] = head[x];
	aim[total] = y;
	head[x] = total;
}

int DFS(int x,int last)
{
	int max_size = 0,size = 1;
	for(int i = head[x];i;i = next[i]) {
		if(aim[i] == last)	continue;
		int temp = DFS(aim[i],x);
		max_size = max(max_size,temp);
		size += temp;
	}
	max_size = max(max_size,points - size);
	if(max_size < ans)
		ans = max_size,p_ans = x;
	return size;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-10-15 02:27:54

POJ 1655 Balancing Act 焦点树的相关文章

poj 1655 Balancing Act 【树的重心】

知识点:树的重心 定义:以这个点为根,那么所有的子树(不算整个树自身)的大小都不超过整个树大小的一半. 性质: 性质 1 :树中所有点到某个点的距离和中,到重心的距离和是最小的,如果有两个距离和,他们的距离和一样. 性质 2 :把两棵树通过某一点相连得到一颗新的树,新的树的重心必然在连接原来两棵树重心的路径上. 性质 3 :一棵树添加或者删除一个节点,树的重心最多只移动一条边的位置. 题目:poj 1655 Balancing Act 题意:给出一颗树,求树的重心点以及重心点删除后中的最大子树.

poj 1655 Balancing Act 求树的重心【树形dp】

poj 1655 Balancing Act 题意:求树的重心且编号数最小 一棵树的重心是指一个结点u,去掉它后剩下的子树结点数最少. (图片来源: PatrickZhou 感谢博主) 看上面的图就好明白了,不仅要考虑当前结点子树的大小,也要"向上"考虑树的大小. 那么其它就dfs完成就行了,son[] 存以前结点为根的结点个数. 这是用邻接表写: 1 #include<iostream> 2 #include<cstdio> 3 #include<cst

POJ 1655 Balancing Act【树的重心】

Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14251   Accepted: 6027 Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or m

POJ 1655 Balancing Act(树的重心)

Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14062   Accepted: 5937 Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or m

POJ 1655 Balancing Act (树的重心,常规)

题意:求树的重心,若有多个重心,则输出编号较小者,及其子树中节点最多的数量. 思路: 树的重心:指的是一个点v,在删除点v后,其子树的节点数分别为:u1,u2....,设max(v)为其中的最大值,点v的max(v)是所有点里面最小的,称v为树的重心. 如何求任一重心?按树形来看,max(v)可以由其父亲贡献,也可以由其任一孩子贡献.孩子比较好解决,不就是深搜一遍,然后回溯时统计下数量就行了?而父亲的怎么办?可以知道,点v到其父亲这一叉就是n-sum(v)了,sum(v)指的是以v为根的子树的节

POJ 1655 Balancing Act(求树的重心)

题目大意: 就是要求树的重心,重心的定义就是删除这个点使得森林尽量平衡. 也可以让分治子树的时候使得每颗子树的数量在nlogn以内. 思路分析: son [x] 表示x的子树的数量  不包括自己. balance 表示最大的森林的节点数. 最后我们要让最大的balance 最小. balance = max (balance ,n - 1 - son[x]  , son[j] +1).. #include <cstdio> #include <iostream> #include

POJ 1655 Balancing Act (树状dp入门)

Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree in the forest T created

POJ 1655 Balancing Act(求树的重心--树形DP)

题意:求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的. 思路:随便选一个点把无根图转化成有根图,dfs一遍即可dp出答案 //1348K 125MS C++ 1127B #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> using namespace std; int

POJ 1655 Balancing Act (树的重心)

题意:求树的重心裸题. 拓展:树的重心可以在树分治时避免退化链时的最坏时间复杂度,提高时间效率. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue&g