[poj3107/poj2378]Godfather/Tree Cutting树形dp
题意:求树的重心(删除该点后子树最大的最小)
解题关键:想树的结构,删去某个点后只剩下它的子树和原树-此树所形成的数,然后第一次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的更多相关文章
- hdu 5909 Tree Cutting [树形DP fwt]
hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...
- POJ 2378.Tree Cutting 树形dp 树的重心
Tree Cutting Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4834 Accepted: 2958 Desc ...
- poj 2378 Tree Cutting 树形dp
After Farmer John realized that Bessie had installed a "tree-shaped" network among his N ( ...
- HDU - 5909 Tree Cutting (树形dp+FWT优化)
题意:树上每个节点有权值,定义一棵树的权值为所有节点权值异或的值.求一棵树中,连通子树值为[0,m)的个数. 分析: 设\(dp[i][j]\)为根为i,值为j的子树的个数. 则\(dp[i][j\o ...
- HDU.5909.Tree Cutting(树形DP FWT/点分治)
题目链接 \(Description\) 给定一棵树,每个点有权值,在\([0,m-1]\)之间.求异或和为\(0,1,...,m-1\)的非空连通块各有多少个. \(n\leq 1000,m\leq ...
- 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 ...
- BZOJ-3227 红黑树(tree) 树形DP
个人认为比较好的(高端)树形DP,也有可能是人傻 3227: [Sdoi2008]红黑树(tree) Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1 ...
- 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 ...
- 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 ...
随机推荐
- 10个迷惑新手的Cocoa&Objective-c开发问题
本文转载至 http://blog.csdn.net/lvxiangan/article/details/27964733 language background runtime thre ...
- python 基础 4.0 函数的一般形式及传参
#/usr/bin/python #coding=utf-8 #@Time :2017/10/23 15:58 #@Auther :liuzhenchuan #@File :函数的一般形式.p ...
- 子串的索引 str.index(sub) sub必须存在
ii.lstrip(' ')[0:2]=='//' ii.lstrip(' ').index('//')==0
- 远程服务器上的weblogic项目管理(二)发布完成后如何重启weblogic容器
前面说到了每次更新服务器项目的java文件与配置文件后,需要更新weblogic容器以完成更新加载,下面来说说如何更新weblogic容器: 第一种方法可以通过ssh shell client工具直接 ...
- (转).NET基础拾遗(5)多线程开发基础
https://www.cnblogs.com/edisonchou/p/4848131.html
- 使用nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器
参考: 1,使用nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器笔记(一)http://blog.csdn.net/xdwyyan/article/details/4319 ...
- LeetCode:分发饼干【455】
LeetCode:分发饼干[455] 题目描述 假设你是一位很棒的家长,想要给你的孩子们一些小饼干.但是,每个孩子最多只能给一块饼干.对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的 ...
- png24 png8 jpeg与gif
png24无损压缩,支持透明,有8位布尔透明通道,支持半透明,生成的图片品质最高,也最大 png8支持透明,有1位布尔透明通道,要么透明.要么半透明,生成的图片很小,只支持256色 jpeg有损压缩, ...
- appium不支持Android7.0系统设备解决办法
1. 找到appium的安装目录下的adb.js文件. 2. 打开adb.js,手动修改该文件下的内容: Adb.prototype.getPIDsByName=function(name,cb){ ...
- LightOJ - 1287 Where to Run —— 期望、状压DP
题目链接:https://vjudge.net/problem/LightOJ-1287 1287 - Where to Run PDF (English) Statistics Forum T ...