题目链接: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的更多相关文章

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

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

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

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

  3. CodeForces 219D Choosing Capital for Treeland (树形DP)

    题意:给一个树形图,n个节点,n-1条有向边,要求选一个节点作为根,使需要改变方向的边的数目最少.并输出所有可能作为根的点. 思路: 先随便一个点进行DFS,计算将每棵子树的边全部往下时,所需要的费用 ...

  4. Codeforces 219D Choosing Capital for Treeland 2次DP

    //选择一个根使得变换最少边的方向使得能够到达所有点#include <map> #include <set> #include <list> #include & ...

  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. Codeforces 219D. Choosing Capital for Treeland (树dp)

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

  7. Codeforces 219D Choosing Capital for Treeland

    http://codeforces.com/problemset/problem/219/D 题目大意: 给出一棵树,但是它的边是有向边,选择一个城市,问最少调整多少条边的方向能使一个选中城市可以到达 ...

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

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

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

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

随机推荐

  1. Debian NAT共享上网

    如果Linux主机有两个网卡,比如一个有线.一个无线,当无线连接后,其他机器即可通过有线共享上网,为了方便叙述,假设环境如下: A机器有两块网卡,eth0和ws0,其中ws0为无线网卡,已连接wifi ...

  2. BFS 和 DFS

    DFS用到递归,BFS要用到一个辅助队列 #include "stdafx.h" #include<iostream> #include<vector> # ...

  3. dede后台title怎么修改的?去掉XXXX-织梦内容管理系统V5.7

    dede后台title怎么修改的? 去掉XXXX-织梦内容管理系统V5.7 打开include/common.inc.php的文件. $cfg_version = 'V57_UTF8_SP1';(这是 ...

  4. 07 nginx Location之正则匹配

    一:Location之正则匹配 再来看,正则也来参与. location / { root   /usr/local/nginx/html; index  index.html index.htm; ...

  5. iOS 生命周期 -init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear 区别和用途

    iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 ...

  6. ios 10 sticker pack application

    看了WWDC2016直播,我们发现变得谨慎而开放的苹果在新一版四大平台系统中展示了很多变化,当然重中之重还是伟大的iOS.通过试用iOS10beta版,除了长大了的更强大的Siri主要感受到iMess ...

  7. PHP-Manual的学习----【语言参考】----【类型】-----【string字符串型】

    1.一个字符串 string 就是由一系列的字符组成,其中每个字符等同于一个字节.这意味着 PHP 只能支持 256 的字符集,因此不支持 Unicode .2. string 最大可以达到 2GB. ...

  8. Java final关键字特点

    一.特点 1.由于继承,方法可以重写,所以父类的功能就会被子类覆盖2.有时候我们不想子类覆盖父类的功能,这时候我们可以使用final关键字3.final可以修饰:类.变量,方法.4.final修饰类, ...

  9. Java static关键字特点

    一.特点 1.随着类的加载而加载2.优先于对象存在3.被类的所有对象共享4.可以通过类名调用 二.调用特征 静态方法: 成员变量:只能访问静态变量 成员方法:只能访问静态成员方法 非静态方法: 成员变 ...

  10. css3中font-face属性的用法详解

    @font-face是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中,随着@font-face模块的出现,我们在Web的开发中使用字体不怕只能使用Web安全字体,你们当中或许有许 ...