题目链接:http://poj.org/problem?id=3107

求树的重心,所谓树的重心就是:在无根树转换为有根树的过程中,去掉根节点之后,剩下的树的最大结点最小,该点即为重心。

剩下的数的 最大结点dp[i]=max(max(s[j]),n-s[i])  其中的s[i]为以i为根节点的子树的结点总数,j为i的孩子。

//思路和代码都是比较好理解的

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=5e4+;
const int INF=0x3f3f3f3f; struct Edge
{
int v;
int next;
} edge[maxn<<]; int dp[maxn];
int s[maxn];
int head[maxn];
int n,k; void init()
{
k=;
memset(head,-,sizeof(head));
} void addedge(int u,int v)
{
edge[k].v=v;
edge[k].next=head[u];
head[u]=k++; edge[k].v=u;
edge[k].next=head[v];
head[v]=k++;
} void dfs1(int u,int p)
{
s[u]=;
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
dfs1(v,u);
s[u]+=s[v];
}
} void dfs2(int u,int p)
{
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
dp[u]=max(dp[u],s[v]);
dfs2(v,u);
}
dp[u]=max(dp[u],n-s[u]);
} int main()
{
while(scanf("%d",&n)==)
{
init();
int a,b;
for(int i=; i<n; i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
}
memset(dp,,sizeof(dp));
dfs1(,-);
dfs2(,-);
int ans=INF;
for(int i=; i<=n; i++)
if(dp[i]<ans) ans=dp[i];
int flag=;
for(int i=; i<=n; i++)
{
if(dp[i]==ans)
{
if(flag==)
{
printf("%d",i);
flag=;
}
else
printf(" %d",i);
}
}
printf("\n");
}
return ;
}

poj1655 题目链接:http://poj.org/problem?id=1655

求树的重心,输出重心和结点最少的树的结点数。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=5e4+;
const int INF=0x3f3f3f3f; struct Edge
{
int v;
int next;
} edge[maxn<<]; int dp[maxn];
int s[maxn];
int head[maxn];
int n,k; void init()
{
k=;
memset(head,-,sizeof(head));
} void addedge(int u,int v)
{
edge[k].v=v;
edge[k].next=head[u];
head[u]=k++; edge[k].v=u;
edge[k].next=head[v];
head[v]=k++;
} void dfs1(int u,int p)
{
s[u]=;
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
dfs1(v,u);
s[u]+=s[v];
}
} void dfs2(int u,int p)
{
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==p) continue;
dp[u]=max(dp[u],s[v]);
dfs2(v,u);
}
dp[u]=max(dp[u],n-s[u]);
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
for(int t=; t<=T; t++)
{
scanf("%d",&n);
init();
int a,b;
for(int i=; i<n; i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
}
memset(dp,,sizeof(dp));
dfs1(,-);
dfs2(,-);
int ans=INF,k;
for(int i=; i<=n; i++)
if(dp[i]<ans) k=i,ans=dp[i];
printf("%d %d\n",k,ans);
}
return ;
}

poj3107 求树的重心(&& poj1655 同样求树的重心)的更多相关文章

  1. poj 2001:Shortest Prefixes(字典树,经典题,求最短唯一前缀)

    Shortest Prefixes Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 12731   Accepted: 544 ...

  2. Codeforces 390E Inna and Large Sweet Matrix 树状数组改段求段

    题目链接:点击打开链接 题意:给定n*m的二维平面 w个操作 int mp[n][m] = { 0 }; 1.0 (x1,y1) (x2,y2) value for i : x1 to x2 for ...

  3. POJ 2104 K-th Number ( 求取区间 K 大值 || 主席树 || 离线线段树)

    题意 : 给出一个含有 N 个数的序列,然后有 M 次问询,每次问询包含 ( L, R, K ) 要求你给出 L 到 R 这个区间的第 K 大是几 分析 : 求取区间 K 大值是个经典的问题,可以使用 ...

  4. [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)

    [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...

  5. 树链剖分与倍增求LCA

    树链剖分与倍增求\(LCA\) 首先我要吐槽机房的辣基供电情况,我之前写了一上午,马上就要完成的时候突然停电,然后\(GG\)成了送链剖分 其次,我没歧视\(tarjan LCA\) 1.倍增求\(L ...

  6. Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作

    什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T ...

  7. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

  8. NYOJ 35 表达式求值(逆波兰式求值)

    http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...

  9. 数论-质数 poj2689,阶乘分解,求阶乘的尾零hdu1124, 求尾零为x的最小阶乘

    /* 要求出[1,R]之间的质数会超时,但是要判断[L,R]之间的数是否是素数却不用筛到R 因为要一个合数n的最大质因子不会超过sqrt(n) 所以只要将[2,sqrt(R)]之间的素数筛出来,再用这 ...

  10. 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分

    树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...

随机推荐

  1. 【hihoCoder】第20周 线段树

    题目: 输入 每个测试点(输入文件)有且仅有一组测试数据. 每组测试数据的第1行为一个整数N,意义如前文所述. 每组测试数据的第2行为N个整数,分别描述每种商品的重量,其中第i个整数表示标号为i的商品 ...

  2. 【Git】笔记4 分支管理1

    1.创建与合并分支 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点: 每次提交,master分支都会向 ...

  3. LightOJ 1236 - Pairs Forming LCM(素因子分解)

    B - Pairs Forming LCM Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  4. ios安装cocoaPods

    1. 安装 a. 查看源 i.   gem sources -l b. 删除源 i.   sudo gem sources -r https://rubygems.org/ c. 设置源 i.   s ...

  5. ecgcd(解二元不定方程)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=775 关于扩展欧几里得算法还是推一遍好啦: 有方程:a*x+b*y=d=gcd(a, b) ...

  6. 微信支付 - V3支付问题

    参考资料:http://www.2cto.com/weixin/201506/407690.html   1.微信公众号支付出错: 当前页面的URL未注册: get_brand_wcpay_reque ...

  7. jQueryEasyUi验证

        多重验证: { field : 'startPort', title : "起始端口", editor: "text", width : 50, edi ...

  8. 重温WCF之一个服务实现多个契约(二)

    public class ServiceImp : IService1,IService2,IService3 { public string SayHelloA() { return "你 ...

  9. Delphi中uses在interfeace和implementation中的区别

    use单元引入分为在interface中引入,如 interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Co ...

  10. Pyqt QComboBox 省市区县联动效果

    在Qt中, QComboBox方法窗口组件允许用户从列表清单中选择,在web中就是select标签,下拉选项. 省市区县的联动就是currentIndexChanged 获取当前的Index,通过这个 ...