题干:

The country Treeland consists of n cities, some pairs of them are connected with unidirectional roads. Overall there are n - 1 roads in the country. We know that if we don't take the direction of the roads into consideration, we can get from any city to any other one.

The council of the elders has recently decided to choose the capital of Treeland. Of course it should be a city of this country. The council is supposed to meet in the capital and regularly move from the capital to other cities (at this stage nobody is thinking about getting back to the capital from these cities). For that reason if city a is chosen a capital, then all roads must be oriented so that if we move along them, we can get from city a to any other city. For that some roads may have to be inversed.

Help the elders to choose the capital so that they have to inverse the minimum number of roads in the country.

Input

The first input line contains integer n (2 ≤ n ≤ 2·105) — the number of cities in Treeland. Next n - 1 lines contain the descriptions of the roads, one road per line. A road is described by a pair of integers si, ti (1 ≤ si, ti ≤ nsi ≠ ti) — the numbers of cities, connected by that road. The i-th road is oriented from city si to city ti. You can consider cities in Treeland indexed from 1 to n.

Output

In the first line print the minimum number of roads to be inversed if the capital is chosen optimally. In the second line print all possible ways to choose the capital — a sequence of indexes of cities in the increasing order.

Examples

Input

3
2 1
2 3

Output

0
2

Input

4
1 4
2 4
3 4

Output

2
1 2 3 

题目大意:

给出N个点,其中有N-1条有向边,边的方向可以改变,问最少改变多少条边可以从某一个点到达任意一个点,同时求出这些点。

解题报告:

给一段一句话题解:

要改变的边的权值为1,不需要改变的边的权值为0,两次dfs,第一次算出以1点为根节点到所有点要改变的边数,第二次以1为根节点向下遍历节点3 算出每一个点到达所有点要改变的边数,dp[son]+=(dp[root]-dp[son])+((tree[i].val)?-1:1),某一点的值是他父节点4 的值减去他以前的值再考虑他与父节点之间的边的方向。

其实就是两边dfs就好了,第一遍是正常的递归以cur为根的状态值,第二遍求出转移到cur的那一半的状态值。也就是第一次dfs是用儿子更新父亲,第二次dfs是用父亲处理一下之后来更新儿子。好题啊精妙的!!

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
int n;
int a,b;
ll dp[MAX];//指向我的有多少条边
ll ans[MAX];
struct Node {int to;bool f;//1==实边,0==虚边 Node(){}Node(int to,int f):to(to),f(f){}
};
vector<Node> vv[MAX];
void dfs(int cur,int root) {int up = vv[cur].size();for(int i = 0; i<up; i++) {Node v = vv[cur][i];if(v.to == root) continue;dfs(v.to,cur);dp[cur] += dp[v.to];if(v.f == 0) dp[cur]++; }
}
void DFS(int cur,int root) {int up = vv[cur].size();for(int i = 0; i<up; i++) {Node v = vv[cur][i];if(v.to == root) continue;dp[v.to] += (dp[cur]-dp[v.to]);if(v.f) dp[v.to]++;else dp[v.to]--;DFS(v.to,cur);}
}
int main()
{cin>>n;for(int i = 1; i<=n-1; i++) {scanf("%d%d",&a,&b);vv[a].pb(Node(b,1));vv[b].pb(Node(a,0));}dfs(1,-1);DFS(1,-1);ll minn = 0x3f3f3f3f3f;for(int i = 1; i<=n; i++) minn = min(minn,dp[i]);printf("%lld\n",minn);int ans = 0;for(int i = 1; i<=n; i++) {if(minn == dp[i]) printf("%d ",i);}return 0 ;}

总结: 代码中DFS中无意间调用了dfs,TLE8了,,但是没有wa,,仔细想一下确实是不会wa的,,这里的dp不会再重新算一遍,因为叶子结点的dp永远没有改变过,所以不会出现多调用一次dfs就会使每个节点dp的值成倍的增加的现象。所以其实在这里多调用一次dfs顶多算是重新求了一次dp的值,并不会使dp改变成原来的多少倍那样、、

注意DFS的更新顺序,,不然就会出错!!总之牢牢把握住,更新状态的前提是所用的值一定是所需的完成值就好了。

【CodeForces - 219D 】Choosing Capital for Treeland (树形dp)相关推荐

  1. Codeforces - Choosing Capital for Treeland

    题目链接:Codeforces - Choosing Capital for Treeland 显然,如果确定首都之后,我们可以O(n)计算出这个点的答案. 然后这个东西可以换根吗?显然是可以的.换根 ...

  2. Codeforces 671D. Roads in Yusland(树形DP+线段树)

    调了半天居然还能是线段树写错了,药丸 这题大概是类似一个树形DP的东西.设$dp[i]$为修完i这棵子树的最小代价,假设当前点为$x$,但是转移的时候我们不知道子节点到底有没有一条越过$x$的路.如果 ...

  3. CodeForces - 856B Similar Words(AC自动机+树形dp)

    题目链接:点击查看 题目大意:给出一个大小为 n 的字符串集记为 X,给出两个字符串相似的定义为:如果某个字符串去掉首字母可以得到另一个字符串 现在需要构造一个尽可能大的字符串集,满足以下两个条件: ...

  4. CodeForces - 1092F Tree with Maximum Cost(树形dp+树根转移)

    题目链接:点击查看 题目大意:给出一个树,每个顶点都有一个权值,任意一点到其他点的距离为经过边的数量,求出一点到其他每一个点的距离*权值之和最大 题目分析:树形dp,一开始怎么也想不明白,看了别人的代 ...

  5. CodeForces - 1118F1 Tree Cutting (Easy Version)(树形dp)

    题目链接:点击查看 题目大意:给定n个点,每个点的权值分别对应颜色:0:无颜色,1:红色,2:蓝色,现在需要切割边,使切割后的两个部分不能出现红色和蓝色掺杂的部分,也就是说两个部分必须只能各自含有一个 ...

  6. 树形DP——Codeforces Choosing Capital for Treeland

    http://codeforces.com/problemset/problem/219/D 题意:给一个n节点的有向无环图,要找一个这样的点:该点到其它n-1要逆转的道路最少,(边<u,v&g ...

  7. Codeforces 815C. Karen and Supermarket【树形DP】

    LINK 思路 首先发现依赖关系是一个树形的结构 然后因为直接算花多少钱来统计贡献不是很好 因为数组开不下 那就可以算一个子树里面选多少个的最小代价就可以了 注意统计贡献的时候用优惠券的答案只能在1号 ...

  8. CodeForces 771C Bear and Tree Jumps 树形DP

    题意: 给出一棵树,一个人可以在树上跳,每次最多跳\(k(1 \leq k \leq 5)\)个点 定义\(f(s,t)\)为从顶点\(s\)跳到顶点\(t\)最少需要跳多少次 求\(\sum\lim ...

  9. Codeforces 1088E Ehab and a component choosing problem(树形DP)

    Codeforces 1088E Ehab and a component choosing problem(树形DP) 题意 给一棵树,要求从中选一些联通分量,使得平均联通分量重量总和最大.如果有多 ...

最新文章

  1. c#_winform打开关闭时淡入淡出
  2. Java开发者必须知道的内存泄漏问题
  3. linux解决windows应用程序,关于Linux下使用Windows应用程序的尝试总结
  4. 显微镜自动聚焦原理是什么_什么是共聚焦显微镜?你了解过共聚焦显微镜吗?...
  5. MySQL的lock tables和unlock tables的用法
  6. 开启、关闭数据库mysql
  7. 用Python开始机器学习(2:决策树分类算法)
  8. 迅捷pdf在线转换html,迅捷pdf在线转换成word免费版在线版
  9. python 绘制降水量色斑图
  10. js正则表达式校验手机号码和电话号码
  11. 采写编杂志采写编杂志社采写编编辑部2022年第10期目录
  12. PIC单片机c语言休眠,PIC16F72 休眠程序
  13. 如何选择和阅读科技论文
  14. 咸鱼的 Github 情报 | 一个支持边下边播、无版权限制和自动上传的BT离线下载程序...
  15. leetcode_Restore IP Addresses
  16. 如何让自己时刻冷静的方法_怎么让心静下来(让心静下来的5种方法)
  17. 表单验证设计的用户体验基本原则
  18. 去除停用词并绘制词云图
  19. mysql多字段联合搜索和concat带来的问题
  20. 我爱你,与你无关 【没有我的可怜人儿】

热门文章

  1. rsync的原理和安装使用及配制详解(三)(转)
  2. 你是个有魅力的人吗?人格魅力这样修养而成
  3. 关于Java中的HashMap
  4. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]46.Sigma协议正确性、公正性和零知识性
  5. 【数据结构与算法】排序优化
  6. [Leetcode][JAVA]第[29]题[两数相除][二分法]
  7. [Leedcode][JAVA][第837题][新21点][动态规划][数学]
  8. c语言三阶素数魔方阵,用C语言构造3*3素数魔方阵,即找出9个不大于500的素数并排成魔方阵。...
  9. java 对象访问权限_Java面向对象编程之访问控制权限
  10. asm扩容流程_Oracle rac asm 扩容