Codeforces 219D Choosing Capital for Treeland:Tree dp
题目链接:http://codeforces.com/problemset/problem/219/D
题意:
给你一棵树,n个节点。
树上的边都是有向边,并且不一定是从父亲指向儿子的。
你可以任意翻转一些边的方向。
现在让你找一个节点,使得从这个节点出发能够到达其他所有节点,并保证翻转边的数量最小。
问你最少翻转多少条边,并输出所有满足此条件的节点编号。
题解:
本题要解两个dp: dp1 & dp2
首先考虑dp1:
表示状态:
dp1[i]表示使节点i能够到达i的子树中的所有节点,翻转边的最小数量。
如何转移:
dp1[i] = ∑ (dp1[son] + 边<i,son>由i指向son ? 0 : 1)
dfs一遍即可。
然后求dp2:
表示状态:
dp2[i]表示使节点i能够到达这棵树的所有节点,翻转边的最小数量。
如何转移:
dp2[i] = dp2[par] + 边<par,i>是否由par指向i ? 1 : -1
如果边<par,i>由par指向i,那么在dp2[par]中这条边是不会被翻转的,所以此时应该将它翻转,代价+1。
如果边<par,i>由i指向par,那么在dp2[par]中这条边已经被翻转了一次,然而在dp2[i]中是不需要翻转的,所以将dp2[par]中多余的那次翻转减掉就好。
边界条件:
dp2[1] = dp1[1]
(默认根节点为1)
所以最终答案为dp2[i]中的最小值,然后将所有dp2[i]等于ans的节点输出就好啦。
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#define MAX_N 200005
#define INF 1000000000 using namespace std; struct Edge
{
int dest;
bool flag;
Edge(int _dest,bool _flag)
{
dest=_dest;
flag=_flag;
}
Edge(){}
}; int n;
int ans=INF;
int dp1[MAX_N];
int dp2[MAX_N];
vector<Edge> edge[MAX_N]; void read()
{
cin>>n;
int x,y;
for(int i=;i<n;i++)
{
cin>>x>>y;
edge[x].push_back(Edge(y,true));
edge[y].push_back(Edge(x,false));
}
} void dfs1(int now,int p)
{
dp1[now]=;
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(temp.dest!=p)
{
dfs1(temp.dest,now);
dp1[now]+=dp1[temp.dest]+(!temp.flag);
}
}
} void dfs2(int now,int p,bool d)
{
if(now==) dp2[now]=dp1[now];
else dp2[now]=dp2[p]+(d?:-);
ans=min(ans,dp2[now]);
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(temp.dest!=p) dfs2(temp.dest,now,temp.flag);
}
} void work()
{
dfs1(,-);
dfs2(,-,);
cout<<ans<<endl;
for(int i=;i<=n;i++)
{
if(dp2[i]==ans) cout<<i<<" ";
}
cout<<endl;
} int main()
{
read();
work();
}
Codeforces 219D Choosing Capital for Treeland:Tree dp的更多相关文章
- 【题解】codeforces 219D Choosing Capital for Treeland 树型dp
题目描述 Treeland国有n个城市,这n个城市连成了一颗树,有n-1条道路连接了所有城市.每条道路只能单向通行.现在政府需要决定选择哪个城市为首都.假如城市i成为了首都,那么为了使首都能到达任意一 ...
- Codeforces 219D Choosing Capital for Treeland(树形DP)
题目是给一张边有向的树形图.要选出首都的点,首都要都能走到其他点,因此要反转一些边的方向.问可以选哪几个点作为首都,使它们所需反转边的数量最少. 这题挺好想的,因为做过HDU2196. 首先就不妨设正 ...
- CodeForces 219D Choosing Capital for Treeland (树形DP)
题意:给一个树形图,n个节点,n-1条有向边,要求选一个节点作为根,使需要改变方向的边的数目最少.并输出所有可能作为根的点. 思路: 先随便一个点进行DFS,计算将每棵子树的边全部往下时,所需要的费用 ...
- Codeforces 219D Choosing Capital for Treeland 2次DP
//选择一个根使得变换最少边的方向使得能够到达所有点#include <map> #include <set> #include <list> #include & ...
- (纪念第一道完全自己想的树DP)CodeForces 219D Choosing Capital for Treeland
Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes inpu ...
- Codeforces 219D. Choosing Capital for Treeland (树dp)
题目链接:http://codeforces.com/contest/219/problem/D 树dp //#pragma comment(linker, "/STACK:10240000 ...
- Codeforces 219D Choosing Capital for Treeland
http://codeforces.com/problemset/problem/219/D 题目大意: 给出一棵树,但是它的边是有向边,选择一个城市,问最少调整多少条边的方向能使一个选中城市可以到达 ...
- Codeforces 219D - Choosing Capital for Treeland(树形dp)
http://codeforces.com/problemset/problem/219/D 题意 给一颗树但边是单向边,求至少旋转多少条单向边的方向,可以使得树上有一点可以到达树上任意一点,若有多个 ...
- CodeForces 219D Choosing Capital for Treeland (树形DP)经典
<题目链接> 题目大意: 给定一个有向树,现在要你从这颗树上选一个点,使得从这个点出发,到达树上其它所有点所需翻转的边数最小,输出最少需要翻转的边数,并且将这些符合条件的点输出. 解题分析 ...
随机推荐
- 在iOS中实现sticky header
经常在网页中看到这样一种效果,当页面滚动一段距离后,页面中的某个部分固定在一个区域(通常是头部导航),这种效果一般称为Sticky Header,如下图所示: 上述操作在Android系统中非常好实现 ...
- 嵌入式开发之simulation--- 双目移动dsp机器人
http://foundy.blog.163.com/blog/static/263383442014112391130207/
- 对象复制帮助类---DeepCopy
有的时候我们在对一个引用类型的对象进行传递操作的时候希望不要直接修改传递过来的对象,而是复制出一份来操作的时候就可以用下面的类进行复制 sing System.IO; using System.Run ...
- JQuery基础知识--方便忘记时查看
第一次写博客,不多说废话,实用为先.如有不对,请多指正. JQuery api 第一步引入JQuery库. <script type="text/javascript" sr ...
- PHP-Manual的学习----【语言参考】----【基本语法】
2017年6月28日11:29:311.当解析一个文件时,PHP 会寻找起始和结束标记,也就是 <?php 和 ?>,这告诉 PHP 开始和停止解析二者之间的代码.此种解析方式使得 PHP ...
- python在windows下安装paramiko模块和安装pycrypto模块(3步搞定)(转)
Python中使用SSH需要用到OpenSSH,而OpenSSH依赖于paramiko模块,而paramiko模块又依赖于pycrypto模块,因此要在Python中使用SSH,我们需要先安装pycr ...
- wordpress 获取分类ID,分类标题,分类描述,分类链接url函数
get_cat_ID() 根据分类名称获取分类ID ///// get_cat_name() 根据分类ID获取分类名称 用法:<?phpget_cat_ID( $cat_name ...
- 图解堆算法、链表、栈与队列(Mark)
原文地址: 图解堆算法.链表.栈与队列(多图预警) 堆(heap),是一类特殊的数据结构的统称.它通常被看作一棵树的数组对象.在队列中,调度程序反复提取队列中的第一个作业并运行,因为实际情况中某些时间 ...
- ASP获取上月本月下月的第一天和最后一天
上月第一天:<%=dateadd("m",-1,year(date)&"-"&month(date)&"-1" ...
- 2017-2018-1 20179209《Linux内核原理与分析》第九周作业
理解进程调度时机 进程调度时机 中断处理过程(包括时钟中断.I/O中断.系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(): 内 ...