D. Choosing Capital for Treeland

题意

给出一颗有方向的n个节点的树,现在要选择一个点作为首都。

问最少需要翻转多少条边,使得首都可以到所有其他的城市去,以及相应的首都可以是哪些点。

思路

先忽略掉树中的方向,dp[i]表示i节点到它的子树所有点最少需要翻转的边。

进行第一遍dfs

如果u-v的方向是u-->v,那么dp[u]=dp[u]+dp[v];,否则dp[u]=dp[u]+dp[v]+1;,表示u-v这条边要翻转。

这时根节点的dp值就是根节点作为首都需要翻转的边,进行第二遍dfs:

dp[i]表示i作为首都需要翻转的最少边的数量

如果u-v的方向是u-->v,那么dp[v]=dp[u]+1;,否则dp[v]=dp[u]-1

代码

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int N=1e6+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f; vector<int>vec[N],ans;
int n,dp[N];
map<int,map<int,int> >mp;
void dfs(int u,int fa)
{
for(int v:vec[u])
{
if(v==fa) continue;
dfs(v,u);
dp[u]+=(dp[v]+!mp[u][v]);
}
}
void dfs2(int u,int fa)
{
for(int v:vec[u])
{
if(v==fa) continue;
if(mp[u][v]) dp[v]=dp[u]+1;
else dp[v]=dp[u]-1;
dfs2(v,u);
}
}
int main()
{
scanf("%d",&n);
for(int i=1; i<n; i++)
{
int u,v;
scanf("%d%d",&u,&v);
mp[u][v]=1;//mp[u][v]==1,表示u-v的方向是u-->v
vec[u].pb(v);
vec[v].pb(u);
}
dfs(1,0);
dfs2(1,0);
int maxn=inf;
for(int i=1; i<=n; i++)
{
if(dp[i]<maxn)
{
maxn=dp[i];
ans.clear();
ans.pb(i);
}
else if(dp[i]==maxn)
ans.pb(i);
}
printf("%d\n",maxn);
for(int v:ans)
printf("%d ",v);
printf("\n");
return 0;
}

最新文章

  1. rsync同步架构
  2. [AS3.0] NetConnection.Connect.Rejected 解决办法
  3. 调整label中text显示的行间距
  4. 大陆地区OpenStack项目Core现状(截至2016年1月28日,转载自陈沙克日志)
  5. bootstrap-treeview
  6. vue实现一个移动端屏蔽滑动的遮罩层
  7. python高级编程(第12章:优化学习)1
  8. Android -- BroadCastReceiver的简单使用
  9. C++ Primer 学习笔记_63_重载运算符和转换 --转换和类类型【上】
  10. 1.Office 365系列(-)
  11. NYOJ--325--深度优先搜索--zb的生日
  12. 设置通过Maven创建工程的JDK版本
  13. Hadoop 故障整理
  14. python函数之可迭代对象、迭代器的判断
  15. kvm 虚机环境碰到的两个小坑
  16. form-layui
  17. ubuntu14.04 桌面版/服务器版安装DevStack教程
  18. final视频
  19. apache HTML5 History 模式 配置
  20. Nginx配置中文域名

热门文章

  1. F - Bone Collector
  2. sws_接口自动化_demo
  3. 前端学习笔记-JavaScript
  4. 详解 Collections类
  5. TensorFlow-keras 100分类
  6. 005.Ansible de palybook简单使用
  7. 在java中使用JMH(Java Microbenchmark Harness)做性能测试
  8. element-ui 通用表单封装及VUE JSX应用
  9. python- 函数高级
  10. SVN签出,回退