题目直通车:http://codeforces.com/problemset/problem/1029/E

思路大意:在树上做dp,依次更新ar数组,ar[i]表示以i为根节点的子树对答案的最小贡献值,依次更新即可,具体细节见代码

/*
13
1 2
1 3
1 4
4 5
4 6
4 7
7 8
7 9
7 10
10 11
10 12
10 13 output:2
*/ #include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<fstream>
#include<cstdlib>
#include<ctime>
#include<list>
#include<climits>
#include<bitset>
using namespace std;
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout);
#define left asfdasdasdfasdfsdfasfsdfasfdas1
#define tan asfdasdasdfasdfasfdfasfsdfasfdas
typedef long long ll;
typedef unsigned int un;
const int desll[][]={{,},{,-},{,},{-,}};
const ll mod=1e9;
const int maxn=2e5+;
const int maxm=1e6+;
const double eps=1e-;
int m,n;
int ar[maxn];
vector<int> ve[maxn];
int dis[maxn],ans,arTwo[maxn];
int sum,maxx;
//arTwo[i]表示i节点与1相连时,以i为根的子树中需要与1相连的个数
//ar[i]表示以i为根节点的子树中需要与1相连的个数,即对答案的贡献值的最少值,dp更新ar即可
int func(int u,int pre,int num){
int mid=;
for(int i=;i<ve[u].size();i++){
int v=ve[u][i];
if(v==pre)continue;
if(num==)mid += func(v,u,num-);
else mid+=ar[v];
}
return min(mid, ar[u]);
}
void dfs2(int u,int pre){
for(int i=;i<ve[u].size();i++){
int v=ve[u][i];
if(v==pre)continue;
dfs2(v,u);
}
arTwo[u] = func(u,pre,);
ar[u]=arTwo[u]+;//u节点与1相连的情况
int sumMid=,maxMid=-n;
for(int i=;i<ve[u].size();i++){//u节点的一个子节点与1相连的情况
int v=ve[u][i];
if(v==pre)continue;
sumMid += ar[v];
maxMid = max(maxMid, ar[v]-arTwo[v]-);
}
if(sumMid==)sumMid=,maxMid=;//特判子节点的情况
ar[u] = min(ar[u], sumMid-maxMid);
}
void funcDfs(int u,int pre,int num){
if(num==){
int mid=;
for(int i=;i<ve[u].size();i++){
int v=ve[u][i];
if(v==pre)continue;
mid+=ar[v];
}
ans += min(ar[u], mid);
return ;
}
for(int i=;i<ve[u].size();i++){
int v=ve[u][i];
if(v==pre)continue;
funcDfs(v,u,num-);
}
} int main()
{
scanf("%d",&n);
fill(ar,ar+n+,n);
fill(arTwo,arTwo+n+,n);
for(int i=;i<n;i++){
int a,b;scanf("%d%d",&a,&b);
ve[a].push_back(b);
ve[b].push_back(a);
}
ans=;
dfs2(,-);
funcDfs(,,);
printf("%d\n",ans);
return ;
}

Codeforces 1029 E. Tree with Small Distances(树上dp)的更多相关文章

  1. Codeforces 1111 E. Tree(虚树,DP)

    题意 有一棵树,q个询问,每次询问,指定一个点做树根,再给定k个点,要求把这些点分成不超过m组的方案数,分配的限制是任意两个有祖先关系的点不能分在同一组.题目还保证了所有的询问的k加起来不超过1e5. ...

  2. CF E .Tree with Small Distances(树上的贪心)

    题意: 这是一颗有n-1条边的无向树 , 在树上加最少的边使树的1节点到其他节点的距离最多为 2 : 分析:很容易考虑的贪心的做法,但是该如何的贪心呢 ? 我一开始是打算贪心节点的儿子最多那一个 , ...

  3. HDU6446 Tree and Permutation(树上DP)

    传送门:点我 Tree and Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (J ...

  4. Problem - D - Codeforces Fix a Tree

    Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...

  5. 树的最小支配集 E - Cell Phone Network POJ - 3659 E. Tree with Small Distances

    E - Cell Phone Network POJ - 3659 题目大意: 给你一棵树,放置灯塔,每一个节点可以覆盖的范围是这个节点的所有子节点和他的父亲节点,问要使得所有的节点被覆盖的最少灯塔数 ...

  6. CodeForces 690C2 Brain Network (medium)(树上DP)

    题意:给定一棵树中,让你计算它的直径,也就是两点间的最大距离. 析:就是一个树上DP,用两次BFS或都一次DFS就可以搞定.但两次的时间是一样的. 代码如下: #include<bits/std ...

  7. Codeforces Round #526 (Div. 2) D. The Fair Nut and the Best Path 树上dp

    D. The Fair Nut and the Best Path 题意:给出一张图 点有权值 边也要权值 从任意点出发到任意点结束 到每个点的时候都可以获得每个点的权值,而从边走的时候都要消耗改边的 ...

  8. 【题解】彩色树 51nod 1868 虚树 树上dp

    Prelude 题目在这里:ο(=•ω<=)ρ⌒☆ Solution 蒟蒻__stdcall的第一道虚树题qaq. 首先很容易发现,这个排列是假的. 我们只需要求出每对点之间的颜色数量,然后求个 ...

  9. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

随机推荐

  1. USACO Section2.1 Hamming Codes 解题报告 【icedream61】

    hamming解题报告----------------------------------------------------------------------------------------- ...

  2. Python学习记录一

    1.这个在unix类的操作系统才有意义.#!/usr/bin/python是告诉操作系统执行这个脚本的时候,调用/usr/bin下的python解释器:#!/usr/bin/env python这种用 ...

  3. ASP.NET Core ---异常处理

    一.局部异常处理: 在Action里面catch 二.全局异常处理: 1.默认的异常处理配置: 默认配置在StartUp文件的Configure中注册错误处理,显示开发者错误页面: public vo ...

  4. (整)Unreal渲染模块 框总览

    @author: 黑袍小道 随缘查看     说明 由于搬山的渲染这部分担心自己理解错误,故而搬移官方下,后面整个完成再反过来更新 (这当且仅当做Unreal的帮助文档).     图形编程 模块 渲 ...

  5. PCA学习笔记

    主成分分析(Principal Component Analysis,简称PCA)是最常用过的一种降维方法 在引入PCA之前先提到了如何使用一个超平面对所有的样本进行恰当的表达? 即若存在这样的超平面 ...

  6. PHP遍历数组的几种方法

      这三种方法中效率最高的是使用foreach语句遍历数组.从PHP4开始就引入了foreach结构,是PHP中专门为遍历数组而设计的语句,推荐大家使用.先分别介绍这几种方法     PHP中遍历数组 ...

  7. 在python中如何比较两个float类型的数据是否相等

    奇怪的现象 前几天跟同事聊起来,在计算机内部float比较是很坑爹的事情.比方说,0.1+0.2得到的结果竟然不是0.3? >>> 0.1+0.2 0.300000000000000 ...

  8. 【bzoj4994】[Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组

    题目描述 给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数 样例输入 4 3 2 4 4 1 3 2 1 样例输 ...

  9. LeetCode -- Sum Root to Leaf NNumbers

    Related Links: Path Sum: http://www.cnblogs.com/little-YTMM/p/4529982.html Path Sum II: http://www.c ...

  10. CString和string在unicode与非unicode下的相互转换(转)

    原文转自 http://blog.csdn.net/u014303844/article/details/51397556 CString和string在unicode与非unicode下的相互转换 ...