题目大意:

根据题目的图很好理解意思,就是记录每一个点的balance,例如 i 的balance就是把 i 从这棵树中除去后得到的森林中含有结点数最多

的子树中的节点个数,然后找到所有节点中对应的balance的最小值 , 并输出最小值对应的最小的标号

题目不要看花。。。前一个是找最大,后面找所有最大值中的最小,我就是看错一直wa,后来人家题解刚看完题目意思就反应过来 , 囧死了 - -

昨天貌似做过一道类似的题,任意找一点 , 比如 1 作为根进行dfs,第一次dfs记录所有点对应的子树中含有的节点的总个数

第二次dfs记录down[i] , 也就是i子树中 i 连接的所有子树中含有节点数最多的节点个数

其实down[i]就相当 i 出去后 , i 下方森林可得到的最大balance , 还需要求一个 i 上方的balance , 这个上方的值就是n-sum[i]

两者比较取最大就可以了

 #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = ;
int first[N] , k , sum[N] , down[N] , rec[N]; struct Edge{
int y , next;
}e[N<<]; void add_edge(int x , int y)
{
e[k].y = y , e[k].next = first[x];
first[x] = k++;
} void dfs1(int u , int fa)
{
sum[u] = ;
for(int i=first[u] ; i!=- ; i=e[i].next)
{
int v = e[i].y;
if(v == fa) continue;
dfs1(v , u);
sum[u] += sum[v];
}
}
void dfs2(int u , int fa)
{
for(int i=first[u] ; i!=- ; i=e[i].next)
{
int v = e[i].y;
if(v == fa) continue;
down[u] = max(sum[v]+ , down[u]);
dfs2(v , u);
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int T;
scanf("%d" , &T);
while(T--)
{
int n , a , b;
scanf("%d" , &n);
memset(first , - , sizeof(first));
k = ;
for(int i= ; i<n ; i++){
scanf("%d%d" , &a , &b);
add_edge(a , b);
add_edge(b , a);
}
memset(down , , sizeof(down));
dfs1( , -);
dfs2( , -);
int minn = down[]-;
rec[] = down[]-;
// cout<<"down: 1: "<<down[1]<<" "<<sum[1]<<endl;
for(int i= ; i<=n ; i++){
// cout<<"down: i: "<<i<<" "<<" "<<down[i]<<" "<<sum[i]<<endl;
rec[i] = max(down[i]- , n-sum[i]);
minn = min(minn , rec[i]);
}
int i;
for(i= ; i<=n ; i++){
if(rec[i] == minn) break;
}
printf("%d %d\n" , i , minn);
}
return ;
}

POJ 3107

求解问题的思想是和上面的题目是基本相同的,除了输入输出方式需要改变,然后数组开大点就可以照抄上面代码了

 #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = ;
int first[N] , k , sum[N] , down[N] , rec[N]; struct Edge{
int y , next;
}e[N<<]; void add_edge(int x , int y)
{
e[k].y = y , e[k].next = first[x];
first[x] = k++;
} void dfs1(int u , int fa)
{
sum[u] = ;
for(int i=first[u] ; i!=- ; i=e[i].next)
{
int v = e[i].y;
if(v == fa) continue;
dfs1(v , u);
sum[u] += sum[v];
}
}
void dfs2(int u , int fa)
{
for(int i=first[u] ; i!=- ; i=e[i].next)
{
int v = e[i].y;
if(v == fa) continue;
down[u] = max(sum[v]+ , down[u]);
dfs2(v , u);
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int n , a , b;
while(scanf("%d" , &n) == ){
memset(first , - , sizeof(first));
k = ;
for(int i= ; i<n ; i++){
scanf("%d%d" , &a , &b);
add_edge(a , b);
add_edge(b , a);
}
memset(down , , sizeof(down));
dfs1( , -);
dfs2( , -);
int minn = down[]-;
rec[] = down[]-;
// cout<<"down: 1: "<<down[1]<<" "<<sum[1]<<endl;
for(int i= ; i<=n ; i++){
// cout<<"down: i: "<<i<<" "<<" "<<down[i]<<" "<<sum[i]<<endl;
rec[i] = max(down[i]- , n-sum[i]);
minn = min(minn , rec[i]);
}
int num = ;
for(int i= ; i<=n ; i++){
if(rec[i] == minn){
if(num == ) printf("%d" , i);
else printf(" %d" , i);
num++;
}
}
}
return ;
}

POJ 1655 Balancing Act && POJ 3107 Godfather的更多相关文章

  1. POJ.1655 Balancing Act POJ.3107 Godfather(树的重心)

    关于树的重心:百度百科 有关博客:http://blog.csdn.net/acdreamers/article/details/16905653 1.Balancing Act To POJ.165 ...

  2. POJ 1655 Balancing Act&&POJ 3107 Godfather(树的重心)

    树的重心的定义是: 一个点的所有子树中节点数最大的子树节点数最小. 这句话可能说起来比较绕,但是其实想想他的字面意思也就是找到最平衡的那个点. POJ 1655 题目大意: 直接给你一棵树,让你求树的 ...

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

    poj 1655 Balancing Act 题意:求树的重心且编号数最小 一棵树的重心是指一个结点u,去掉它后剩下的子树结点数最少. (图片来源: PatrickZhou 感谢博主) 看上面的图就好 ...

  4. poj 1655 Balancing Act(找树的重心)

    Balancing Act POJ - 1655 题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的. /* 找树的重心可以用树形dp或 ...

  5. POJ 1655 Balancing Act【树的重心】

    Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14251   Accepted: 6027 De ...

  6. POJ 1655.Balancing Act 树形dp 树的重心

    Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14550   Accepted: 6173 De ...

  7. POJ 1655 - Balancing Act 树型DP

    这题和POJ 3107 - Godfather异曲同工...http://blog.csdn.net/kk303/article/details/9387251 Program: #include&l ...

  8. POJ 1655 Balancing Act 树的重心

    Balancing Act   Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. ...

  9. POJ 1655 - Balancing Act - [DFS][树的重心]

    链接:http://poj.org/problem?id=1655 Time Limit: 1000MS Memory Limit: 65536K Description Consider a tre ...

随机推荐

  1. bzoj 1594: [Usaco2008 Jan]猜数游戏【二分+线段树】

    写错一个符号多调一小时系列-- 二分答案,然后判断这个二分区间是否合法: 先按值从大到小排序,然后对于值相同的一些区间,如果没有交集则不合法:否则把并集在线段树上打上标记,然后值小于这个值的区间们,如 ...

  2. CF482C Game with Strings

    题意 你和你的朋友玩一个游戏,游戏规则如下. 你的朋友创造 n 个长度均为 m 的不相同的字符串,然后他随机地选择其中一个.他选择这些字符串的概率是相等的,也就是说,他选择 n 个字符串中的每一个的概 ...

  3. Linux环境下卸载、安装及配置MySQL5.1

    Linux环境下卸载原有MySQL5.1数据库,并重新安装MySQL数据库的示例记录. 一.卸载MySQL 查看主机中是否安装了MySQL数据库: [root@RD-viPORTAL- ~]# rpm ...

  4. c语言数据读入---sscanf、fscanf

    #include <iostream> #include <cstdio> #include <cstring> #include <stdlib.h> ...

  5. 389 Find the Difference 找不同

    给定两个字符串 s 和 t,它们只包含小写字母.字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母.请找出在 t 中被添加的字母.示例:输入:s = "abcd"t = ...

  6. 往文件内写入内容(java)

    新建个工具类,并标记成静态的,方便调用. package util; import java.io.File;import java.io.FileOutputStream; public class ...

  7. 一个用pyton写的监控服务端进程的软件hcm

    使用udp实现,简单,方便,不用三次握手 1. 所有部署服务器进程的机器有一个代理进程hagent,用来监听hcm console中发送过来的命令 2.hcm需要提供以下命令 start :普通方式启 ...

  8. Code Kata:大整数四则运算—除法 javascript实现

    除法不可用手工算法来计算,其基本思想是反复做减法,看从被除数里面最多能减去多少个除数,商就是多少. 除法函数: 如果前者绝对值小于后者直接返回零 做减法时,不需要一个一个减,可以以除数*10^n为基数 ...

  9. NX自动出图 发布啦

    经过4个月的努力,终于面世啦!!!!1.安装文件 :http://yunpan.cn/Q49TWSJmy2i5Z    请下载后,按照“安装说明.txt ”进行安装!2.学习视频:http://yun ...

  10. ubuntu服务器全部署

    一.nginx+php+redis+phpredis 二.安装mysql 三.上传web文件 cd /var mkdir www cd www/ mkdir html cd html/ rz (apt ...