CodeForces 219D Choosing Capital for Treeland (树形DP)
题意:给一个树形图,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)的更多相关文章
- Codeforces 219D - Choosing Capital for Treeland(树形dp)
http://codeforces.com/problemset/problem/219/D 题意 给一颗树但边是单向边,求至少旋转多少条单向边的方向,可以使得树上有一点可以到达树上任意一点,若有多个 ...
- CodeForces 219D Choosing Capital for Treeland (树形DP)经典
<题目链接> 题目大意: 给定一个有向树,现在要你从这颗树上选一个点,使得从这个点出发,到达树上其它所有点所需翻转的边数最小,输出最少需要翻转的边数,并且将这些符合条件的点输出. 解题分析 ...
- CF 219D Choosing Capital for Treeland 树形DP 好题
一个国家,有n座城市,编号为1~n,有n-1条有向边 如果不考虑边的有向性,这n个城市刚好构成一棵树 现在国王要在这n个城市中选择一个作为首都 要求:从首都可以到达这个国家的任何一个城市(边是有向的) ...
- Codeforces 219D. Choosing Capital for Treeland (树dp)
题目链接:http://codeforces.com/contest/219/problem/D 树dp //#pragma comment(linker, "/STACK:10240000 ...
- (纪念第一道完全自己想的树DP)CodeForces 219D Choosing Capital for Treeland
Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes inpu ...
- CF#135 D. Choosing Capital for Treeland 树形DP
D. Choosing Capital for Treeland 题意 给出一颗有方向的n个节点的树,现在要选择一个点作为首都. 问最少需要翻转多少条边,使得首都可以到所有其他的城市去,以及相应的首都 ...
- CF219D. Choosing Capital for Treeland [树形DP]
D. Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes i ...
- Codeforces 219D Choosing Capital for Treeland(树形DP)
题目是给一张边有向的树形图.要选出首都的点,首都要都能走到其他点,因此要反转一些边的方向.问可以选哪几个点作为首都,使它们所需反转边的数量最少. 这题挺好想的,因为做过HDU2196. 首先就不妨设正 ...
- 【题解】codeforces 219D Choosing Capital for Treeland 树型dp
题目描述 Treeland国有n个城市,这n个城市连成了一颗树,有n-1条道路连接了所有城市.每条道路只能单向通行.现在政府需要决定选择哪个城市为首都.假如城市i成为了首都,那么为了使首都能到达任意一 ...
- [codeforces219D]Choosing Capital for Treeland树形dp
题意:给出一棵树,带有向边,找出某个点到达所有点需要反转的最少的边. 解题关键:和求树的直径的思路差不多,将求(父树-子树)的最大值改为求特定值.依然是两次dfs,套路解法. 对树形dp的理解:树形d ...
随机推荐
- [hdu1277]全文检索(AC自动机)
解题关键:AC自动机模板题,注意字符匹配时若无法匹配,直接用%s即可. #include<bits/stdc++.h> using namespace std; typedef long ...
- JSP提交表单的几种方法
1.通过<form action="url"><input type="submit"></form>按钮方式提交 这种方式 ...
- 20个Flutter实例视频教程-第13节: 展开闭合案例
20个Flutter实例视频教程-第13节: 展开闭合案例 视频地址: https://www.bilibili.com/video/av39709290/?p=13 博客地址: https://js ...
- UVa 10755 Garbage Heap (暴力+前缀和)
题意:有个长方体由A*B*C组成,每个废料都有一个价值,要选一个子长方体,使得价值最大. 析:我们暴力枚举上下左右边界,然后用前缀和来快速得到另一个,然后就能得到长方体,每次维护一个最小值,然后差就是 ...
- aria2安装webui
安装aria2 yum install aria2 安装完成后可以使用简单命令进行下载 aria2c http://example.org/mylinux.iso aria2c -c -s http: ...
- 16-CoreData之多表关联(存储自定义数据模型)
多表关联 1.1-简介 什么是多表关联 在处理数据库的关系中,无非只有三种关系 一对一:一个老师只能在一个教室上课,不可能同时在两个教室上课 一对多:一个教室可以有多个学生,但一个学生只能在一个教室 ...
- 玩转phpstorm之terminal
启动快捷键 Alt+F12 启动之后,像这样 第一次进入这个配置默认显示的是cmd窗口,现在我们将其换成git 命令行窗口,毕竟git才是boss first 将cmd换成我们是先在电脑上安装完成的 ...
- 基于ndk_r7_windows编译实现ndk项目,不需要cygwin
下面就介绍下Android NDK的入门学习过程: 入门的最好办法就是学习Android自带的例子, 这里就通过学习Android的NDK自带的demo程序:hello-jni来达到这个目的. 一. ...
- Ogre 中使用OIS的两种模式
关于OIS的输入 要开始考虑游戏输入的问题了,以及开始加入CEGUI也要考虑加入输入的问题.先把OIS的输入简单回忆一下. OIS有两种输入模式:非缓冲输入以及缓冲输入. 无论用哪种输入方式,都应该有 ...
- Linux安装Loadrunner generator
安装环境:redhat 6.5 64位版 从网上下载 loadrunner-11-load-generator.iso 文件 先创建一个iso 目录,用来挂载 iso 文件 mkdir iso 挂载i ...