题意:求树的重心(删除该点后子树最大的最小)

解题关键:想树的结构,删去某个点后只剩下它的子树和原树-此树所形成的数,然后第一次dp求每个子树的节点个数,第二次dp求解答案即可。

此题一开始一直T,后来加了输入挂才过,第一次见卡cin+关同步的题目。

用scanf试了一下,也可以过,0.5s,看来cin关同步和scanf差距也是蛮大的。

任何时候树形dp在dfs中做两次循环都是没必要的。只要了解是先序遍历和后序遍历,在一个for中处理即可。

poj2378将改为n/2即可。

优化:循环的部分少了 最终141ms

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+;
int head[maxn],tot,n;
struct edge{
int to;
int nxt;
int w;
}e[maxn<<]; void add_edge(int u,int v,int w){
e[tot].to=v;
e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot++;
}
int dp[maxn<<],cnt[maxn]; void dfs(int u,int fa){
cnt[u]=;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dfs(v,u);
cnt[u]+=cnt[v];
dp[u]=max(dp[u],cnt[v]);
}
dp[u]=max(n-cnt[u],dp[u]);
}
inline int read(){
char k=;char ls;ls=getchar();for(;ls<''||ls>'';k=ls,ls=getchar());
int x=;for(;ls>=''&&ls<='';ls=getchar())x=(x<<)+(x<<)+ls-'';
if(k=='-')x=-x;return x;
}
int main(){
n=read();
memset(head,-,sizeof head);
tot=;
int a,b;
for(int i=;i<n-;i++){
a=read();
b=read();
add_edge(a,b,);
add_edge(b,a,);
}
dfs(,-);
int ans=inf;
for(int i=;i<=n;i++){
ans=min(ans,dp[i]);
}
bool flag=false;
for(int i=;i<=n;i++){
if(dp[i]==ans){
if(flag) printf(" ");
printf("%d",i);
flag=true;
}
}
printf("\n");
return ;
}

一:219ms

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+;
int head[maxn],tot,n;
struct edge{
int to;
int nxt;
int w;
}e[maxn<<];
void add_edge(int u,int v,int w){
e[tot].to=v;
e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot++;
}
int dp[maxn<<],cnt[maxn];
void dfs(int u,int fa){
cnt[u]=;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dfs(v,u);
cnt[u]+=cnt[v];
}
dp[u]=n-cnt[u];
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dp[u]=max(dp[u],cnt[v]);
}
} inline int read(){
char k=;char ls;ls=getchar();for(;ls<''||ls>'';k=ls,ls=getchar());
int x=;for(;ls>=''&&ls<='';ls=getchar())x=x*+ls-'';
if(k=='-')x=-x;return x;
}
int main(){
//ios::sync_with_stdio(0);
//cin.tie(0);
//cout.tie(0);
n=read();
memset(head,-,sizeof head);
tot=;
int a,b;
for(int i=;i<n-;i++){
//scanf("%d%d",&a,&b);
//cin>>a>>b;
a=read();
b=read();
add_edge(a,b,);
add_edge(b,a,);
}
dfs(,-);
int ans=inf;
for(int i=;i<=n;i++){
ans=min(ans,dp[i]);
}
bool flag=false;
for(int i=;i<=n;i++){
if(dp[i]==ans){
if(flag) printf(" ");
printf("%d",i);
flag=true;
}
}
printf("\n");
return ;
}

两个dfs分开的形式,练习一下。读入挂将*10变为(x<<3)+(x<<1),变为188ms了。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+;
int head[maxn],tot,n;
struct edge{
int to;
int nxt;
int w;
}e[maxn<<]; void add_edge(int u,int v,int w){
e[tot].to=v;
e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot++;
}
int dp[maxn<<],cnt[maxn]; void dfs(int u,int fa){
cnt[u]=;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dfs(v,u);
cnt[u]+=cnt[v];
}
} void dfs2(int u,int fa){
dp[u]=n-cnt[u];
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dfs2(v,u);
dp[u]=max(dp[u],cnt[v]);
}
} inline int read(){
char k=;char ls;ls=getchar();for(;ls<''||ls>'';k=ls,ls=getchar());
int x=;for(;ls>=''&&ls<='';ls=getchar())x=(x<<)+(x<<)+ls-'';
if(k=='-')x=-x;return x;
}
int main(){
//ios::sync_with_stdio(0);
//cin.tie(0);
//cout.tie(0);
n=read();
memset(head,-,sizeof head);
tot=;
int a,b;
for(int i=;i<n-;i++){
//scanf("%d%d",&a,&b);
//cin>>a>>b;
a=read();
b=read();
add_edge(a,b,);
add_edge(b,a,);
}
dfs(,-);
dfs2(,-);
int ans=inf;
for(int i=;i<=n;i++){
ans=min(ans,dp[i]);
}
bool flag=false;
for(int i=;i<=n;i++){
if(dp[i]==ans){
if(flag) printf(" ");
printf("%d",i);
flag=true;
}
}
printf("\n");
return ;
}

[poj3107/poj2378]Godfather/Tree Cutting树形dp的更多相关文章

  1. hdu 5909 Tree Cutting [树形DP fwt]

    hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...

  2. POJ 2378.Tree Cutting 树形dp 树的重心

    Tree Cutting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4834   Accepted: 2958 Desc ...

  3. poj 2378 Tree Cutting 树形dp

    After Farmer John realized that Bessie had installed a "tree-shaped" network among his N ( ...

  4. HDU - 5909 Tree Cutting (树形dp+FWT优化)

    题意:树上每个节点有权值,定义一棵树的权值为所有节点权值异或的值.求一棵树中,连通子树值为[0,m)的个数. 分析: 设\(dp[i][j]\)为根为i,值为j的子树的个数. 则\(dp[i][j\o ...

  5. HDU.5909.Tree Cutting(树形DP FWT/点分治)

    题目链接 \(Description\) 给定一棵树,每个点有权值,在\([0,m-1]\)之间.求异或和为\(0,1,...,m-1\)的非空连通块各有多少个. \(n\leq 1000,m\leq ...

  6. HDU5834 Magic boy Bi Luo with his excited tree(树形DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5834 Description Bi Luo is a magic boy, he also ...

  7. BZOJ-3227 红黑树(tree) 树形DP

    个人认为比较好的(高端)树形DP,也有可能是人傻 3227: [Sdoi2008]红黑树(tree) Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1 ...

  8. Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)

    题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input ...

  9. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

随机推荐

  1. 导出到Excel中NPOI

    源地址:http://www.cnblogs.com/dreamof/archive/2010/06/02/1750151.html\ 1.NPOI官方网站:http://npoi.codeplex. ...

  2. yum 安装 mysql5.5 mysql 5.6 mysql5.7

      一. yum 安装mysql5.6 1. 安装仓库 要使用yum 安装mysql,需要使用mysql的yum 仓库,先从官网下载适合你的系统仓库 http://dev.mysql.com/down ...

  3. 2017-2018-1 20179209《Linux内核原理与分析》第四周作业

    本周学习内容为<跟踪分析MenuOS简单linux系统的启动过程>和教材中的进程调度及内核数据结构. 一.跟踪分析Linux内核的启动过程 这个实验我是在实验楼环境中完成的,最初想在自己的 ...

  4. 题解 P1387 【最大正方形】

    传送门 搞不清楚为什么这一题要DP . . . . . . 思路: \(n\le100\),考虑暴力. 要求一大块区间内都是1,考虑前缀和. 在矩阵中求一个符合条件的子矩阵,考虑\(n^3\)的&qu ...

  5. PHP通过session id 实现session共享和登录验证的代码

    先说说,这个机制的用途吧,到现在为止战地知道这个机制有两个方面的用途: 首先,多服务器共享session问题,这个大家应该都能够理解的,当一个网站的用户量过大,就会使用服务器集群,例如专门有一个登录用 ...

  6. Thinkphp2.2 config.inc.php常用配置

    CHECK_FILE_CASE -- windows环境下面的严格检查大小写. /* 项目设定 */    'APP_DEBUG'    => false, // 是否开启调试模式    'AP ...

  7. ceph分布式存储系统初探

    前言 由于公司的业务调整,现在我又要接触ceph这个东西,由于我接手的是一个网盘类项目,所以分布式存储系统ceph就是我必须要学的了.现在压力还是比较大的,从业务直接到后台核心. 大概在这几天,我将c ...

  8. Algorithm: inversion

    inversion就是逆序对 题目:现给出一个数列,求该数列中的逆序对数(逆序数).本节给出三种方法:方法一是最直接的暴力方法:方法二是基于归并分治的思想:方法三是基于线段树的.   [解法一] 暴力 ...

  9. BZOJ 3671 NOI2014 随机数生成器

    这题其实是个暴力. 首先那一堆如何构造n*m方格的东西都是在玩你. 构造出来方阵后,由于是一个排列,不存在重复,可以大力贪心. 每次将选出一个最小的元素,然后将它右上左下的元素全部打上标记(记得bre ...

  10. BZOJ3262 陌上花开 —— 三维偏序 CDQ分治

    题目链接:https://vjudge.net/problem/HYSBZ-3262 3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit ...