D. Choosing Capital for Treeland
time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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

巧妙的转换,正向边权0,逆向边权1

两遍dfs分别求f[i]到子节点的边权和 和 g[i]从i往上的边权和

注意把ans=min(ans,f[u]+g[u]);写在dfs开始处,否则处理不了1最小的时候

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=2e5+,INF=1e9+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,u,v;
struct edge{
int v,w,ne;
}e[N<<];
int cnt=,h[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].w=;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].w=;e[cnt].ne=h[v];h[v]=cnt;
}
int f[N];
void dfs1(int u,int fa){
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v,w=e[i].w;
if(v==fa) continue;
dfs1(v,u);
f[u]+=f[v]+w;
}
}
int g[N],ans=INF;
void dfs2(int u,int fa){//printf("u %d %d %d\n",u,f[u],g[u]);
ans=min(ans,f[u]+g[u]);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v,w=e[i].w;
if(v==fa) continue;
g[v]=g[u]+f[u]-f[v]+(w==?:-);
dfs2(v,u);
}
}
int main(){
n=read();
for(int i=;i<=n-;i++){u=read();v=read();ins(u,v);}
dfs1(,);
dfs2(,);
printf("%d\n",ans);
for(int i=;i<=n;i++) if(g[i]+f[i]==ans) printf("%d ",i);
}

CF219D. Choosing Capital for Treeland [树形DP]的更多相关文章

  1. CF#135 D. Choosing Capital for Treeland 树形DP

    D. Choosing Capital for Treeland 题意 给出一颗有方向的n个节点的树,现在要选择一个点作为首都. 问最少需要翻转多少条边,使得首都可以到所有其他的城市去,以及相应的首都 ...

  2. CF 219D Choosing Capital for Treeland 树形DP 好题

    一个国家,有n座城市,编号为1~n,有n-1条有向边 如果不考虑边的有向性,这n个城市刚好构成一棵树 现在国王要在这n个城市中选择一个作为首都 要求:从首都可以到达这个国家的任何一个城市(边是有向的) ...

  3. Codeforces 219D - Choosing Capital for Treeland(树形dp)

    http://codeforces.com/problemset/problem/219/D 题意 给一颗树但边是单向边,求至少旋转多少条单向边的方向,可以使得树上有一点可以到达树上任意一点,若有多个 ...

  4. [codeforces219D]Choosing Capital for Treeland树形dp

    题意:给出一棵树,带有向边,找出某个点到达所有点需要反转的最少的边. 解题关键:和求树的直径的思路差不多,将求(父树-子树)的最大值改为求特定值.依然是两次dfs,套路解法. 对树形dp的理解:树形d ...

  5. CodeForces 219D Choosing Capital for Treeland (树形DP)经典

    <题目链接> 题目大意: 给定一个有向树,现在要你从这颗树上选一个点,使得从这个点出发,到达树上其它所有点所需翻转的边数最小,输出最少需要翻转的边数,并且将这些符合条件的点输出. 解题分析 ...

  6. CF219D Choosing Capital for Treeland

    嘟嘟嘟 树形dp. 首先一个很常规的想法就是如果u到v有一条边,那么建立cost(u, v) = 0, cost(v, u) = 1的两条边. 可以两遍dfs. 先任选一个点作为根节点,第一遍从下往上 ...

  7. Codeforces 219D. Choosing Capital for Treeland (树dp)

    题目链接:http://codeforces.com/contest/219/problem/D 树dp //#pragma comment(linker, "/STACK:10240000 ...

  8. CF 219 D:Choosing Capital for Treeland(树形dp)

    D. Choosing Capital for Treeland 链接:http://codeforces.com/problemset/problem/219/D   The country Tre ...

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

    题目传送门 /* 题意:求一个点为根节点,使得到其他所有点的距离最短,是有向边,反向的距离+1 树形DP:首先假设1为根节点,自下而上计算dp[1](根节点到其他点的距离),然后再从1开始,自上而下计 ...

随机推荐

  1. oracle实用sql之将逗号分割的字符串分割多个列

    select regexp_substr('a,b,c,','[^,]+',1,rownum) from dual connect by rownum<=length(regexp_replac ...

  2. JavaScript一词被《牛津大词典》收录了

    早上看VS Team的推特发了这个图片,以前总爱问Java怎么读,现在好了,有标准发音了. 确定是 扎瓦·死磕瑞普特 ,哈哈,以后不要再念加瓦了. …… Last month JavaScript r ...

  3. Java 代码完成删除文件、文件夹操作

    import java.io.File;/** * 删除文件和目录 * */public class DeleteFileUtil {    /**     * 删除文件,可以是文件或文件夹     ...

  4. WNMP集成环境下配置thinkPHP

    在网上查了许多解决方法,下面是自己测试过能行的方法,只需在nginx.conf文件添加内容就可以了. 打开nginx.conf文件 ## Try the requested URI as files ...

  5. java web学习总结(九) -------------------通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下:

  6. BUTTONS V. 2.0.0——CSS按钮库

    BUTTONS-V2-CSS库样式职责 CSS库样式职责分离优点 模块样式命名更清晰化 易于维护.扩展性强 动画效果——修改样式后有过度效果,默认样式 源码如下 <!DOCTYPE html&g ...

  7. 向上弹出菜单jQuery插件

    插件名:柯乐义英文名:Keleyijs文件名称:jquery.keleyi.js插件功能:该插件可以让你轻易地在页面上构建一个向上弹出的二级菜单. 示例查看:http://keleyi.com/kel ...

  8. js 理解new的运行机制

    先上段代码: function People(name) { this.name = name; } People.prototype.sayName = function () { console. ...

  9. HTML5学习笔记四 HTML文本格式化

    HTML 格式化标签 HTML 使用标签<b> 与<i> 对输出的文本进行格式, 如:粗体 or 斜体 这些HTML标签被称为格式化标签 通常标签 <strong> ...

  10. OC笔记一:Objective-C简介

    1.OC简介 全称:Objective-C,是扩充C的面向对象编程语言,主要用于iOS和Mac OS开发. C语言的基础上,增加了一层最小的面向对象语法 完全兼容C语言 可以在OC代码中混入C语言代码 ...