[poj3107]Godfather_树形dp_树的重心

Godfather poj-3107

    题目大意:求树的重心裸题。

    注释:n<=50000.

      想法:我们尝试用树形dp求树的重心,关于树的重心的定义在题目中给的很明确。关于这道题,我们邻接矩阵存不下,用链式前向星存边,然后对于任选节点遍历,然后在回溯是进行最大值的最小值更新,之后就是一点显然的结论——树最多只有两个重心,而且这两个加点必须连边。

    最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int k;
int nxt[100050];
int to[100050];
int head[100050];
int g=0;
int sum[100050];
int maxj[100050];
int minn=0x7f7f7f7f;
int a,b;
void dfs(int d,int fa)
{
	for(int i=head[d];i!=0;i=to[i])
	{
		int z=nxt[i];
		if(z!=fa)
		{
			dfs(z,d);
		}
	}
	maxj[d]=max(maxj[d],n-sum[d]-1);
	minn=min(minn,maxj[d]);
	sum[d]+=1;
	sum[fa]+=sum[d];
	maxj[fa]=max(sum[d],maxj[fa]);
	return;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<n;++i)
	{
		scanf("%d%d",&a,&b);
		nxt[++g]=b;
		to[g]=head[a];
		head[a]=g;

		nxt[++g]=a;
		to[g]=head[b];
		head[b]=g;
	}
	dfs(1,0);
	for(int i=1;i<=n;++i)
	{
		if(maxj[i]==minn)
		{
			printf("%d ",i);
		}
	}
	puts("");
	return 0;
}

    小结:第二道树形dp,upupup

原文地址:https://www.cnblogs.com/ShuraK/p/8530468.html

时间: 2024-10-11 13:21:38

[poj3107]Godfather_树形dp_树的重心的相关文章

hdu-4118 Holiday&#39;s Accommodation(树形dp+树的重心)

题目链接: Holiday's Accommodation Time Limit: 8000/4000 MS (Java/Others)     Memory Limit: 200000/200000 K (Java/Others) Problem Description Nowadays, people have many ways to save money on accommodation when they are on vacation.One of these ways is exc

POJ3107Godfather[树形DP 树的重心]

Godfather Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6121   Accepted: 2164 Description Last years Chicago was full of gangster fights and strange murders. The chief of the police got really tired of all these crimes, and decided to

【poj1655】【poj3107】【求树的重心】

先来说一下怎样来求树的直径: 假设 s-t这条路径为树的直径,或者称为树上的最长路 现有结论,从任意一点u出发搜到的最远的点一定是s.t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜就可以找出树的最长路 证明: 1 设u为s-t路径上的一点,结论显然成立,否则设搜到的最远点为T则 dis(u,T) >dis(u,s) 且 dis(u,T)>dis(u,t) 则最长路不是s-t了,与假设矛盾 2 设u不为s-t路径上的点 首先明确,假如u走到了s-t路径上的一点,

POJ 1655 Balancing Act (树形dp 树的重心)

Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10596   Accepted: 4398 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

cqyz oj | 树的分治 | 树形DP | 树的重心

Description 给定一棵N个节点的带权树,定义dist(u,v)为u,v两点间的最短路径长度,路径的长度义为路径上所有边的权和.再给定一个K,如果对于不同的两个结点a,b,如果满足dist(a,b)<=K,则称(a,b)为合法点对. 你的任务是求合法点对个数. Input 第一行包含两个个整数N和K,接下来的N-1行,每行包含三个整数:u,v,len,表示树边(u,v)的长度len. Output 一个整数,表示合法点对的数目. Sample Input 1 5 4 1 2 3 1 3

poj 1655 and 3107 and 2378 树形dp(树的重心问题)

简单的树形dp,顺便学习了树的重心的概念,即以该点为根的树的最大子树的结点数最少. poj 1655: 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 20001; 7 int head[N]; 8 int balance[N]; 9 int child[N]; 10 int n, e; 11 12 struct

树形DP求树的重心 --SGU 134

令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心的属性值. 考虑用树形DP. dp[u]表示割去u点,得到的连通分支的节点数的最大值. tot[u]记录以u为根的这棵子树的节点数总和(包括根). 则用一次dfs即可预处理出这两个数组.再枚举每个点,每个点的属性值其实为max(dp[u],n-tot[u]),因为有可能最大的连通分支在u的父亲及以上

POJ 1655 Balancing Act[树的重心/树形dp]

Balancing Act 时限:1000ms 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

树形dp求树的重心

Balancing Act http://poj.org/problem?id=1655 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int M=50010; 8 vector<int> g[