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

解题关键:想树的结构,删去某个点后只剩下它的子树和原树-此树所形成的数,然后第一次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. Java 学习 day04

    17-数组(概述-内存结构) 概念:同一种类型数据的集合,其实数组就是一个容器. 可以自动给数组中的元素从0开始编号,方便操作这些元素. int[] x = new int[3]; 01-数组(静态初 ...

  2. 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂

    [BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...

  3. 【BZOJ4435】[Cerc2015]Juice Junctions Tarjan+hash

    [BZOJ4435][Cerc2015]Juice Junctions Description 你被雇佣升级一个旧果汁加工厂的橙汁运输系统.系统有管道和节点构成.每条管道都是双向的,且每条管道的流量都 ...

  4. 【题解】cycle

    [题解]cycle 题目描述 给定一个无向图,求一个环,使得环内边权\(\div\)环内点数最大. 数据范围 \(n \le 5000\) \(m\le 10000\) \(Solution\) 考虑 ...

  5. centos 安装postgresql 完整版

    按步骤 执行命令即可: yum install https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-c ...

  6. memcache-session-manager(flexjson)

    MSM项目FlexJson序列化参考文档. 序号(步骤) 需求描述 jar包列表: spymemcached-2.11.1.jar memcached-session-manager-tc8-1.8. ...

  7. matlab 在机器视觉中常用的函数

    ~ triangulate() 三角化(获得距离)匹配点 ~ undistortImage() 去除相机畸变并生成图像

  8. Tomcat部署java项目java.lang.OutOfMemoryError异常解决方法

    java.lang.OutOfMemoryError异常解决方法 Window系统环境下,在catalina.bat文件第一行添加以下内容 set JAVA_OPTS=-Xms512m -Xmx512 ...

  9. JAVA- String类练习

    JAVA- String类练习 需求1:去除字符串两边空格的函数,写一个自己的trim(); public class TestTrim { public static void main(Strin ...

  10. 图解mysql join

    原文:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins 这个图文解释mysql join的各种技 ...