Codeforces Round #135 (Div. 2) D 树形dp

//任选一个根节点,用dfs搜两遍,第一遍找以该节点为根节点

//每一个节点的子树中的相反的边

//第二遍dfs以同样的根节点搜索一遍,记录从根节点到该节点

//正向边和反向边dp[u] = dp[root] - sum_0 + sum_1 ;

#include<cstdio>

#include<cstring>

#include<iostream>

using namespace std ;

const int maxn = 200010 ;

const int inf  = 0x7fffffff ;

int dp[maxn] ;

int vis[maxn] ;

struct Edge

{

int v ;

int flag ;

int next ;

}edge[maxn*2];

int head[maxn] ; int nedge = 0 ;

int st = 1;

int mi  ;

void addedge(int u , int v)

{

edge[nedge].v = v;

edge[nedge].next = head[u];

edge[nedge].flag = 1 ;

head[u] = nedge++ ;

edge[nedge].v = u ;

edge[nedge].next = head[v] ;

edge[nedge].flag = 0;

head[v] = nedge++;

}

void dfs(int u)

{

vis[u] = 1;

for(int i = head[u];i != -1 ;i = edge[i].next)

{

int v = edge[i].v ;

if(vis[v]) continue ;

if(edge[i].flag == 0)

dp[u]++ ;

dfs(v) ;

dp[u] += dp[v];

}

}

void dfs_s(int u , int sum_1 , int sum_0)

{

vis[u] = 1;

dp[u] = dp[st] + sum_1 - sum_0;

mi = min(mi , dp[u]) ;

for(int i = head[u];i != -1 ;i = edge[i].next)

{

int v = edge[i].v;

if(vis[v])continue ;

if(edge[i].flag == 1)

dfs_s(v , sum_1+1 , sum_0) ;

else

dfs_s(v , sum_1 ,sum_0+1);

}

}

void init()

{

memset(head , -1 ,sizeof(head));

memset(dp , 0 , sizeof(dp)) ;

nedge = 0;

memset(vis , 0 , sizeof(vis)) ;

}

int main()

{

// freopen("input.txt","r",stdin);

// freopen("output.txt","w",stdout) ;

int n ;

while(~scanf("%d" ,&n))

{

int u , v;

init() ;

for(int i = 1;i < n;i++)

{

scanf("%d%d" ,&u , &v) ;

addedge(u ,v);

}

mi = inf;

dfs(st) ;

memset(vis , 0 , sizeof(vis)) ;

dfs_s(st , 0 , 0);

int flag = 0 ;

printf("%d\n" ,mi);

for(int i = 1;i <= n;i++)

if(dp[i] == mi)

{

if(flag)printf(" ");

flag = 1;

printf("%d" ,i) ;

}

puts("") ;

}

return  0;

}

时间: 2024-10-18 13:08:58

Codeforces Round #135 (Div. 2) D 树形dp的相关文章

Codeforces Round #168 (Div. 1)B 树形dp

//给一棵树,每次操作可以将包括顶点1的连通子集的所有点的节点加1或减1 //问最少几次操作使得这棵树的所有顶点的值都为0 //以1为根节点建树 //将加和减分开考虑,用up[u],down[u]表示以u为跟节点的子树中需要加的操作 //最大为up[u] ,需要减的操作最大为down[u] //其余的加和减的操作则可以在处理这两个操作时一起覆盖 //在将u的子数全都处理完后u点的值由于在加了up[u]和减了down[u]后变为 //一个新的值,则对于这个新的值根据它的正负并入up[u]或down

Codeforces Round #148 (Div. 1)C 树形dp

//枚举所有边,把该树分为两个树,分别求两颗数的最小的改变量 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 3030 ; const int inf = 0x7fffffff ; int dp[maxn] ; struct Edge { int flag , v; int u ; int next ; }edge[2*maxn] ;

Codeforces Round #530 (Div. 2) E (树形dp+线段树)

链接: 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干需要花费bi时间,有两个玩家,玩家一可以移动到当前点的子节点也可以申请游戏结束返回根节点并吃沿途的饼干,玩家二可以删除当前点到儿子节点的一条边,走路和吃饼干都消耗时间,会给出一个总时间,在总时间内尽可能的多吃饼干,问最多能吃多少个? 思路: 由于是玩家一先手,那么最开始的最大边则不会被删除,但之后路途的最大边都会被玩家二删除,所以我们对于当前点我们需要求: 1.如果现在回头那么最多可以吃到多少饼干 2.向下

树形DP Codeforces Round #135 (Div. 2) D. Choosing Capital for Treeland

题目传送门 1 /* 2 题意:求一个点为根节点,使得到其他所有点的距离最短,是有向边,反向的距离+1 3 树形DP:首先假设1为根节点,自下而上计算dp[1](根节点到其他点的距离),然后再从1开始,自上而下计算dp[v], 4 此时可以从上个节点的信息递推出来 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <cmath> 9 #include <vector> 10 using name

贪心 Codeforces Round #135 (Div. 2) C. Color Stripe

题目传送门 1 /* 2 贪心:当m == 2时,结果肯定是ABABAB或BABABA,取最小改变量:当m > 2时,当与前一个相等时, 改变一个字母 3 同时不和下一个相等就是最优的解法 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 using namespace std; 9 10 const int MAXN = 5e5 + 10; 11 const int IN

构造 Codeforces Round #135 (Div. 2) B. Special Offer! Super Price 999 Bourles!

题目传送门 1 /* 2 构造:从大到小构造,每一次都把最后不是9的变为9,p - p MOD 10^k - 1,直到小于最小值. 3 另外,最多len-1次循环 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 using namespace std; 10 11 typedef long long ll; 12 const i

Codeforces Round #139 (Div. 2)C Barcode DP

#include<iostream> #include<cstdio> #include<cstring> using namespace std ; const int maxn = 1010; const int inf = 0x3f3f3f3f ; int dp[maxn][2] ; char str[maxn][maxn] ; int num[maxn]; int sum_b[maxn]; int sum_w[maxn]; int main() { // fre

Codeforces Round #276 (Div. 1)D.Kindergarten DP贪心

D. Kindergarten In a kindergarten, the children are being divided into groups. The teacher put the children in a line and associated each child with his or her integer charisma value. Each child should go to exactly one group. Each group should be a

Codeforces Round #271 (Div. 2) D.Flowers DP

D. Flowers We saw the little game Marmot made for Mole's lunch. Now it's Marmot's dinner time and, as we all know, Marmot eats flowers. At every dinner he eats some red and white flowers. Therefore a dinner can be represented as a sequence of several