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

解题关键:想树的结构,删去某个点后只剩下它的子树和原树-此树所形成的数,然后第一次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. 通过srvctl add命令添加database信息到srvctl管理器

    ================================================通过srvctl add命令添加database信息到srvctl管理器================ ...

  2. python 基础 7.1 datetime 获得时间

    一 datatime 的使用   object         timedeta         tzinfo         time         data                dat ...

  3. 九度OJ 1013:开门人和关门人 (排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5052 解决:2563 题目描述:     每天第一个到机房的人要把门打开,最后一个离开的人要把门关好.现有一堆杂乱的机房签到.签离记录,请 ...

  4. vs2013工程下的各个文件和文件夹的作用

    1 ipch文件夹 用来加速编译,里面存放的是precompiled headers,即预编译好了的头文件. 头文件也是需要编译的,比如需要处理#ifdef,需要替换宏以及需要include其它头文件 ...

  5. 使用服务端的临时密钥,不依赖阿里js的putFIle--》阿里oss

    <!DOCTYPE html> <html lang='en'> <head> <meta charset='UTF-8'> <title> ...

  6. 【题解】Making The Grade(DP+结论)

    [题解]Making The Grade(DP+结论) VJ:Making the Grade HNOI-D2-T3 原题,禁赛三年. 或许是我做过的最简单的DP题了吧(一遍过是什么东西) 之前做过关 ...

  7. 【题解】CF359B Permutation

    [题解]CF359B Permutation 求一个长度为\(2n\)的序列,满足\(\Sigma |a_{2i}-a_{2i-1}|-|\Sigma a_{2i}-a_{2i-1}|=2k\) 这种 ...

  8. myeclipse安装tomactserver图解

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/shaozucheng/article/details/36673227 选择标题栏中 Window- ...

  9. pm2 的使用

    pm2.json 代码如下 [{ "name" : "dingtalk-mobile", "script" : "app.js&q ...

  10. API的理解和使用——有序集合

    有序集合常用的命令 命令 功能 zadd key score member [score member ... ] 添加元素 zcard key 计算成员个数 zscore key member 计算 ...