hdu4714(树形dp)
2016-06-13 14:40
465 查看
链接:点击打开链接
题意:给出一棵树,删除一条边或者加入一条边的代价都是1,蚊最后使n个节点连成环所需的最小代价
代码:
题意:给出一棵树,删除一条边或者加入一条边的代价都是1,蚊最后使n个节点连成环所需的最小代价
代码:
#pragma comment(linker,"/STACK:1024000000,1024000000") #include <vector> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; vector<int> G[1000005]; int dp[1000005][3],vis[1000005]; //dp[i][j]表示以i为根节点的子树,可用度 void dfs(int s){ //为j时树的分支数,也就是还可以连j个节点 int i,tmp; //时树的分支数 vis[s]=1; dp[s][0]=dp[s][1]=dp[s][2]=1; for(i=0;i<G[s].size();i++){ tmp=G[s][i]; if(!vis[tmp]){ dfs(tmp); //两个分支合并则减1 dp[s][0]=min(dp[s][0]+dp[tmp][0],dp[s][1]+dp[tmp][1]-1); dp[s][1]=min(dp[s][1]+dp[tmp][0],dp[s][2]+dp[tmp][1]-1); dp[s][2]=dp[s][2]+dp[tmp][0]; //保证s节点为根的子树可用度为2,则不能在向上添加节点 } } } int main(){ int i,j,t,u,v,n,ans; scanf("%d",&t); while(t--){ ans=0; memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(i=1;i<=n;i++) G[i].clear(); for(i=1;i<n;i++){ scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } dfs(1); ans=min(min(dp[1][0],dp[1][1]),dp[1][2]); printf("%d\n",2*ans-1); //知道分支数,则答案就是分支数-1+分支数,也就是 } //先分离在合并 return 0; }
相关文章推荐
- 大型网站架构系列:缓存在分布式系统中的应用(一)
- CentOS 企业级 ----Zabbix 搭建
- OnGlobalLayoutListener获得一个视图的高度
- javascript中的this,JS中this的几种基本指向
- Tomcat配置优化经验
- Java IO实例操作
- oracle length&vsize
- Dataframe加载数据的4种方法
- TCP为什么需要3次握手与4次挥手
- Linux下Tomcat的启动、关闭、杀死进程
- Jquery实现动态添加html
- 使用for循环打印输出1000以内的水仙花数
- java文件下载 rest
- Java精度工具类
- 面试题8:旋转数组的最小数字
- 关于JDialog中添加组件无法显示的问题
- nohup
- BeanNameAware接口和BeanFactoryAware接口
- ios开发笔记之十四--用代码来监听按钮的点击
- RGB颜色表