题意:给一个树形图,n个节点,n-1条有向边,要求选一个节点作为根,使需要改变方向的边的数目最少。并输出所有可能作为根的点。

思路:

  先随便一个点进行DFS,计算将每棵子树的边全部往下时,所需要的费用down[i]。还是那个点进行DFS,这次就要求答案了,尝试将每个点t作为根,那么以t作为根的总费用=down[t]+父亲这棵子树。down[t]已经在第一次DFS中求出,而父亲这棵子树就不是down[父亲]了,而是down[父亲]-down[t]+w(父亲,t)。注:w为边权。

 #include <bits/stdc++.h>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=2e5+; struct node
{
int from,to,rev,next;
node(){};
node(int from,int to,int rev,int next):from(from),to(to),rev(rev),next(next){};
}edge[N*];
int head[N], n, edge_cnt;
void add_node(int from,int to,int rev)
{
edge[edge_cnt]=node(from,to,rev,head[from]);
head[from]=edge_cnt++;
} int down[N]; //down[i]表示是往下到点i
void DFS(int t,int far)
{
node e;
for(int i=head[t]; i!=-; i=e.next) //递归先算子树的
{
e=edge[i];
if(e.to^far) DFS(e.to, t);
}
int sum=;
for(int i=head[t]; i!=-; i=e.next) //再算自己的
{
e=edge[i];
if(e.to^far) sum+=down[e.to]+e.rev;
}
down[t]=sum; //只有1种情况:所有子树全部向下
} int ans[N], big;
void DFS2(int t,int far,int val)
{
node e;
ans[t]=down[t]+val; //以本节点为根
big=min(big, ans[t]);
for(int i=head[t]; i!=-; i=e.next)
{
e=edge[i];
if(e.to^far)
{
int r=ans[t]-down[e.to]-e.rev+(e.rev^);
DFS2(e.to, t, r);
}
}
} void init()
{
memset(head, -, sizeof(head));
memset(down, 0x3f, sizeof(down));
edge_cnt=;
big=INF;
} int main()
{
//freopen("input.txt", "r", stdin);
init();
scanf("%d",&n);
for(int i=,a,b; i<n; i++)
{
scanf("%d%d",&a,&b);
add_node(a,b,); //正向
add_node(b,a,);
}
DFS(,-);
DFS2(,-,);
printf("%d\n",big);
for(int i=; i<=n; i++) //输出解
if(big==ans[i])
printf("%d ",i);
return ;
}

AC代码

CodeForces 219D Choosing Capital for Treeland (树形DP)的更多相关文章

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

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

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

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

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

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

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

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

  5. (纪念第一道完全自己想的树DP)CodeForces 219D Choosing Capital for Treeland

    Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes inpu ...

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

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

  7. CF219D. Choosing Capital for Treeland [树形DP]

    D. Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes i ...

  8. Codeforces 219D Choosing Capital for Treeland(树形DP)

    题目是给一张边有向的树形图.要选出首都的点,首都要都能走到其他点,因此要反转一些边的方向.问可以选哪几个点作为首都,使它们所需反转边的数量最少. 这题挺好想的,因为做过HDU2196. 首先就不妨设正 ...

  9. 【题解】codeforces 219D Choosing Capital for Treeland 树型dp

    题目描述 Treeland国有n个城市,这n个城市连成了一颗树,有n-1条道路连接了所有城市.每条道路只能单向通行.现在政府需要决定选择哪个城市为首都.假如城市i成为了首都,那么为了使首都能到达任意一 ...

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

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

随机推荐

  1. asp.net中FileUpload得到上传文件的完整路径

    asp.net中FileUpload得到上传文件的完整路径 Response.Write("完整路径:" + Server.MapPath(FileUpload1.PostedFi ...

  2. Google 马来西亚主页被黑

    互联网并没有想象中安全,Google 马来西亚主页被黑 | TheVerge 消… 查阅全文 ›

  3. Product it again

    题意:求解 $$\prod_{1 \leq i \leq n} \prod_{1 \leq j \leq m} {(i,j)}$$ 解法: 满脑子的反演 考虑对于第一个质数 $p$ 的贡献为 $p^{ ...

  4. JS正则表达式(一)

    正则表达常用符号 /..../  开始结束 ^ 开始 $ 结束 /s 任何非空字符  /S 非空 /d  匹配一个数字=[0-9] /D  匹配一个非数字=[^0-9] /w   匹配一个数字,下划线 ...

  5. 3-2if条件结构

    不同条件做不同的操作.例如满100就减去20 条件结构 package com.imooc.operator; public class ConditionDemo1 { public static ...

  6. eclipse修改某一个项目的字符编码

    eclipse修改某一个项目的字符编码   1 选中要修改编码的文件,鼠标右键,选择[Properties]  2 左侧选中[Resource], 右侧出现[Text file encoding], ...

  7. BlocksKit的使用

    一.引言 众所周知Block已被广泛用于iOS编程.它们通常被用作可并发执行的逻辑单元的封装,或者作为事件触发的回调.Block比传统回调函数有2点优势: 允许在调用点上下文书写执行逻辑,不用分离函数 ...

  8. 525. Contiguous Array

    Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1. ...

  9. [Xcode 实际操作]七、文件与数据-(22)使用OCR光学字符识别技术识别银行卡号码

    目录:[Swift]Xcode实际操作 本文将演示如何使用光学字符识别技术,识别信用卡上的卡号. OCR技术是光学字符识别的缩写(Optical Character Recognition), 是通过 ...

  10. python 函数 之 用户注册register()

    db_path='db.txt' #定义默认文件路径,方便修改def get_uname(): while True: uname=input('请输入用户名:').strip() if uname. ...