树形dp——Tree2cycle
2024-10-18 03:41:21
一、问题描述(题目链接)
给你一棵树,删除或添加一条边的费用都是1,问使它变成一个环的最小费用。
二、解题思路
回溯法,然后回溯的时候的当前节点度数>2(如果是成环的话肯定就是2或者小于2)就把它和父节点之间的边砍掉。每砍掉一次,以后是要连上的,只需乘2就行。由于是回溯回来的,父节点在子节点阶段就考虑了一次,相当于与该子节点与父节点没有边了,所以父节点的度数减1。
三、代码实现
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std; const int maxn = + ;
vector<int>G[maxn];
int degree[maxn],ans,n; void init()
{
ans = ;
memset(degree, , sizeof(degree));
for (int i = ; i <= n; i++)
G[i].clear();
} void dfs(int son, int fa)
{
int k = G[son].size();
for (int i = ; i < k; i++)
{
int newson = G[son][i];
if (newson == fa) continue;
dfs(newson, son);
if (degree[newson] > )
{
degree[son]--; //父节点要减一
ans += (degree[newson] - ) * ;
}
}
} int main()
{
int T;
scanf("%d", &T);
while (T--)
{
int a, b;
init();
scanf("%d", &n);
for (int i = ; i < n; i++)
{
scanf("%d%d", &a, &b);
degree[a]++;
degree[b]++;
G[a].push_back(b);
G[b].push_back(a);
}
int root = ;
for (int i = ; i <= n; i++) //找到度数为一的节点作为根节点,开始搜索
{
if (degree[i] == )
{
root = i;
break;
}
}
dfs(root, );
printf("%d\n", ans + );
}
return ;
}
最新文章
- Leetcode: Sentence Screen Fitting
- C语言杂谈(二)自增运算符++与间接访问运算符*的结合关系和应用模式
- sqlserver锁表、解锁、查看锁表
- 转: 学习开源项目的若干建议(infoq)
- Java语言基础(五) Java原始数据类型的分类以及数据范围
- C# Wpf双向绑定实例
- Strurts(四)——从Struts原型模拟看大道至简(含实例下载)
- HBase 5、Phoenix使用
- Storyboard、Nib文件和代码来实现UI的利与弊
- nio简介
- [原创.数据可视化系列之十二]使用 nodejs通过async await建立同步数据抓取
- python重试(指数退避算法)
- 联动加入redmine的wik
- VIM编辑器使用
- 将base64转为图片
- 初识:java虚拟机的内存划分
- 精读《C++ primer》学习笔记(第四至六章)
- 关于python的GIL全局解释器锁的简单理解
- java final、finally、finalize
- 安全运维之:Linux后门入侵检测工具的使用
热门文章
- now code——处女座的期末复习
- 算法学习--Day8
- Codeforces 358D【DP】
- jpa使用原生SQL查询数据库like的用法
- 2014-5-10 NOIP模拟赛 by coolyangzc
- CF1110F Nearest Leaf
- A. Office Keys ( Codeforces Round #424 (Div. 1, rated, based on VK Cup Finals) )
- gem install 提示rubygems.org连接不上的问题
- [未读]angularjs权威教程
- public private protected 三种访问修饰符在c#中的区别