一个国家,有n座城市,编号为1~n,有n-1条有向边

如果不考虑边的有向性,这n个城市刚好构成一棵树

现在国王要在这n个城市中选择一个作为首都

要求:从首都可以到达这个国家的任何一个城市(边是有向的)

所以一个城市作为首都,可能会有若干边需要改变方向

现在问,选择哪些城市作为首都,需要改变方向的边最少。

输出最少需要改变方向的边数

输出可以作为首都的编号

树形DP

先假定城市1作为首都

令tree(i)表示以i为根的子树

dp[i]表示在tree(i)中,若以i为首都的话,需要改变的边数

第一次dfs,求出dp数组

ans[i]表示在整棵树中,若以i为首都的话,需要改变的边数(注意和dp数组的意义的区别)

明显:ans[1]=dp[1]

明显有:

在一棵有向树中,若首都为u,现在我们要让u的儿子节点v为首都,只需要改变1条边的方向

假设节点u是节点v的父节点,e=(u,v),ans[u]已知

若e的方向指向v,则:ans[v]=ans[u]+1

否则:ans[v]=ans[u]-1

所以第二次dfs,递推求出ans数组

接着,找出min=min(ans[i]),并输出min

输出所有使得ans[i]==min的i

 #include<cstdio>
#include<cstring> using namespace std; const int maxn=+; struct Edge
{
int to,next;
bool flag;
};
Edge edge[maxn<<];
int head[maxn];
int tot;
int ans[maxn];
int dp[maxn];
int print[maxn]; void init()
{
memset(head,-,sizeof head);
tot=;
memset(dp,,sizeof dp);
} void addedge(int u,int v,bool flag)
{
edge[tot].to=v;
edge[tot].flag=flag;
edge[tot].next=head[u];
head[u]=tot++;
} void dfs0(int ,int );
void dfs1(int ,int ); int main()
{
int n;
init();
bool cnt=true;
scanf("%d",&n);
for(int i=;i<n;i++)
{
int u,v;
scanf("%d %d",&u,&v);
addedge(u,v,cnt);
addedge(v,u,!cnt);
}
dfs0(,-);
ans[]=dp[];
dfs1(,-); int min=ans[];
for(int i=;i<=n;i++)
{
if(ans[i]<min)
min=ans[i];
}
tot=;
for(int i=;i<=n;i++)
{
if(ans[i]==min)
{
print[tot++]=i;
}
} printf("%d\n",min);
for(int i=;i<tot-;i++)
{
printf("%d ",print[i]);
}
printf("%d\n",print[tot-]); return ;
} void dfs0(int u,int pre)
{
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
bool flag=edge[i].flag;
if(v==pre)
continue;
dfs0(v,u);
if(flag)
dp[u]+=dp[v];
else
dp[u]+=(dp[v]+);
}
return ;
} void dfs1(int u,int pre)
{
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
int flag=edge[i].flag;
if(v==pre)
continue;
if(flag)
ans[v]=ans[u]+;
else
ans[v]=ans[u]-;
dfs1(v,u);
}
return ;
}

CF 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#135 D. Choosing Capital for Treeland 树形DP

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

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

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

  5. [CF] 219D Choosing Capital for Treeland

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

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

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

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

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

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

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

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

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

随机推荐

  1. HDU5889 Barricade(最短路)(网络流)

    Barricade Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  2. web前端学习策略

  3. 【NOIP2010】关押罪犯

    一开始看错题了,然后怎么想都想不明白--原题: S 城现有两座监狱,一共关押着 N 名罪犯,编号分别为 1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲 ...

  4. StackTrace,Trim

    一: Environment.StackTrace 可能我们看到最多的就是catch中的e参数,里面会有一个StackTrace,然后不可否认的这玩意太有用了,它会把调用堆栈 中的信息输出出来,有了它 ...

  5. WCF入门教程三[WCF的宿主]

    一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定 ...

  6. java_list,set,map集合

    一.集合定义 集合就是讲诺干用途相同.近似的“数据”结合成一个整体 集合从体系上分为三种 1.列表(List):List集合区分元素的顺序,允许包含相同的元素 2.集(set):Set集合不区分元素的 ...

  7. Storm0.9.4安装 - OPEN 开发经验库

    Storm0.9.4安装 - OPEN 开发经验库 bin/zkServer.sh start /home/guym/down/kafka_2.8.0-0.8.0/config/zookeeper.p ...

  8. kettle常见问题解决

    开源ETL工具kettle系列之常见问题 摘要:本文主要介绍使用kettle设计一些ETL任务时一些常见问题,这些问题大部分都不在官方FAQ上,你可以在kettle的论坛上找到一些问题的答案 1. J ...

  9. Centos Mysql 升级

    如何升级CentOS 6.5下的MySQL CentOS 6.5自带安装了MySQL 5.1,但5.1有诸多限制,而实际开发中,我们也已经使用MySQL 5.6,这导致部分脚本在MySQL 5.1中执 ...

  10. Redis 利用锁机制来防止缓存过期产生的惊群现象-转载自 http://my.oschina.net/u/1156660/blog/360552

    首先,所谓的缓存过期引起的“惊群”现象是指,在大并发情况下,我们通常会用缓存来给数据库分压,但是会有这么一种情况发生,那就是在一定时间 内生成大量的缓存,然后当缓存到期之后又有大量的缓存失效,导致后端 ...