ACM-Divide Tree
As we all know that we can consider a tree as a graph. Now give you a tree with nodes having its weight. We define the weight of a tree is the sum of the weight of all nodes on it. You know we can divide the tree into two subtrees by any edge of the tree. And your task is to tell me the minimum difference between the two subtrees’ weight.
输入
The first line, an integer T (T <= 30), representing T test cases blew.
For each test case, the first line contains one integer N (2 <= N <= 10000), indicating the number of tree’s nodes. Then follow N integers in one line, indicating the weight of nodes from 1 to N.
For next N-1 lines, each line contains two integers Vi and Vj (1 <= Vi, Vj <= N), indicating one edge of the tree.
输出
For each test case, output the minimum weight difference. We assume that the result will not exceed 2^20.
样例输入
1
5
6 3 9 3 1
2 3
3 1
4 1
1 5
样例输出
2
DFS水题
备注:另一个结点的权值=父节点权值-当前结点的权值。
//// Divide Tree.cpp : 定义控制台应用程序的入口点。
////
//
//#include "stdafx.h"
//
//#include <stdio.h>
//#include <string.h>
//#include <cmath>
//#include <iostream>
//using namespace std;
//
//const int maxn = 10005;
//const int INF = 0x3f3f3f3f;
//
//int t, n, graph[maxn][maxn],weight[maxn],vis[maxn];
//int ans,sum[maxn];
//
//
////计算子树权值
////思路:沿着DFS路线就可以确定树的权值
//void sum_weight(int i)
//{
// vis[i] = 1;
//
// sum[i] = weight[i];
//
// for (int j = 1; j <= n; j++)
// {
// if (!vis[j] && graph[i][j])//沿着边搜索没有经过的顶点
// {
// sum_weight(j);
// sum[i] += sum[j];
// }
// }
//}
//
//
//
//void DFS(int i)
//{
// vis[i] = 1;
//
// for (int j = 1; j <= n; j++)
// {
// if (graph[i][j] && !vis[j])//也是沿着边搜索
// {
// //思路:
// //1.一个顶点的权值:s[j]
// //2.另一个顶点的权值:s[i] - s[j]
// int sub_diff = (sum[i] - sum[j]) - sum[j];
// ans = ans < abs(sub_diff) ? ans : abs(sub_diff);
// DFS(j);
// }
// }
//}
//
//int main()
//{
// scanf("%d",&t);
// while (t--)
// {
// memset(graph, 0, sizeof(graph));
// memset(vis, 0, sizeof(vis));
// scanf("%d", &n);
// for (int i = 1; i <= n; i++)
// {
// scanf("%d", &weight[i]);
// }
// for (int i = 1; i <= n-1; i++)
// {
// int v1, v2;
// scanf("%d %d", &v1, &v2);
// graph[v1][v2] = 1;
// graph[v2][v1] = 1;//无向图!!!!
// }
//
// sum_weight(1);
//
// ans = INF;
// memset(vis, 0, sizeof(vis));
// DFS(1);
//
// printf("%d\n",ans);
//
// }
// return 0;
//}
// #include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <cmath>
#include <vector>
#include <string.h>
using namespace std; const int M = ;
const int INF = 0x3f3f3f3f;//c、c++的最大数是十六进制的0x int t, n,ans,weight[M],vis[M],sum[M];
vector<int> G[M]; void sum_weight(int i)
{
vis[i] = ; sum[i] = weight[i]; for (int j = ; j < G[i].size(); j++)
{
int next = G[i][j]; if (!vis[next])//沿着边搜索没有经过的顶点
{
sum_weight(next);
sum[i] += sum[next];
}
}
} void DFS(int i)
{
vis[i] = ; for (int j = ; j < G[i].size(); j++)//直接遍历边比遍历顶点循环次数少,可以达到减枝的目的。
{
int next = G[i][j];
if (!vis[next])//也是沿着边搜索
{
//思路:
//1.一个顶点的权值:s[j]
//2.另一个顶点的权值:s[i] - s[j]
int sub_diff = (sum[] - sum[next]) - sum[next];//为什么这里是sum[1]-sum[j],不是sum[i]-sum[j]????
ans = ans < abs(sub_diff) ? ans : abs(sub_diff);
DFS(next);
}
}
} int main()
{ scanf("%d",&t);
while (t--)
{
memset(vis, , sizeof(vis));
scanf("%d", &n);
for (int i = ; i <= n; i++)
{
scanf("%d", &weight[i]);
G[i].clear();
}
for (int i = ; i <= n - ; i++)
{
int v1, v2;
scanf("%d %d", &v1, &v2);
G[v1].push_back(v2);
G[v2].push_back(v1);
} sum_weight(); ans = INF;
memset(vis, , sizeof(vis));
DFS(); printf("%d\n", ans); } return ;
}
ACM-Divide Tree的更多相关文章
- [swustoj 785] Divide Tree
Divide Tree(0785) 问题描述 As we all know that we can consider a tree as a graph. Now give you a tree wi ...
- [ACM]Link-Cut Tree实现动态树初探
动态树问题是指的一类问题,而不是具体指的某一种数据结构.它主要维护一个包含若干有根树的森林,实现对森林的修改和查询等. 实现动态树的数据结构据说主要有4种,Link-Cut Tree是其中的一种.Li ...
- HDOJ-3065(AC自动机+每个模板串的出现次数)
病毒侵袭持续中 HDOJ-3065 第一个需要注意的是树节点的个数也就是tree的第一维需要的空间是多少:模板串的个数*最长模板串的长度 一开始我的答案总时WA,原因是我的方法一开始不是这样做的,我是 ...
- HDOJ-2896(AC自动机+文本串中出现了哪几个模板串)
病毒侵袭 HDOJ-2896 主要使用AC自动机解决,其次在query函数中改变一下,用来记录每个模板串出现的次数,还有insert函数中记录模板串的编号 需要注意最好使用结构体,而且不能一次性使用m ...
- HDU ACM 1325 / POJ 1308 Is It A Tree?
Is It A Tree? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- 九章算法系列(#3 Binary Tree & Divide Conquer)-课堂笔记
前言 第一天的算法都还没有缓过来,直接就进入了第二天的算法学习.前一天一直在整理Binary Search的笔记,也没有提前预习一下,好在Binary Tree算是自己最熟的地方了吧(LeetCode ...
- [LeetCode] 系统刷题4_Binary Tree & Divide and Conquer
参考[LeetCode] questions conlusion_InOrder, PreOrder, PostOrder traversal 可以对binary tree进行遍历. 此处说明Divi ...
- [LeetCode] 124. Binary Tree Maximum Path Sum_ Hard tag: DFS recursive, Divide and conquer
Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any ...
- Minimal Steiner Tree ACM
上图论课的时候无意之间看到了这个,然后花了几天的时间学习了下,接下来做一个总结. 一般斯坦纳树问题是指(来自百度百科): 斯坦纳树问题是组合优化问题,与最小生成树相似,是最短网络的一种.最小生成树是在 ...
随机推荐
- css选择器优先级排序
浏览器默认属性 < 继承自父元素的属性 < 通配符选择器 < 标签选择器 < 类选择器 < 结构伪类选择器 < id选择器 < 行内样式 < !impo ...
- 网络协议-restful协议
REST Representational State Transfer, 是一种软件架构风格,提供一系列限制指导,用于更好的创建web service. 符合REST 架构风格的web servic ...
- VS2008 error PRJ0002 : 错误的结果 31 (从“C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\rc.exe”返回)。
解决方案,选择属性->配置属性->清单工具->输入和输出->嵌入清单,把是改成否
- day15-Python运维开发基础(json序列化模块、random / time / zipfile / OS模块函数)
1. json序列化模块 # ### json """ 所有编程语言都能够识别的数据格式叫做json,是字符串 json: 将数据类型序列化成字符串 pickle:将数据 ...
- save the transient instance before flushing错误解决办法
错误原因: new了一个新对象,在未保存之前将它保存进了一个新new的对象(也即不是持久态). 解决办法: 在保存或更新之前把这个对象查出来(这样就是一个持久态) <set name=" ...
- ie brower 点击用默认浏览器打开链接
<script> function GetCurrentJumpUrl(){ var eleLink = document.getElementById('adLink'); if(ele ...
- redis长篇介绍
一. 简介 Redis 完全开源免费,遵守BSD协议,高性能的(NOSQL) key-value数据库 BSD 伯克利软件发行版 缓存数据集 所以都在内存上面 Redis 数据类型分为:字符串类型.散 ...
- Jquery插件---渐隐轮播
//需求:打开网页时,每秒钟自动切换下一张图片内容.也可以用鼠标点导航按钮进行图片切换 //代码如下 <!DOCTYPE html> <html lang="en" ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:快速浮动
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- ThinkPad重大更新!5款创意设计PC齐发2日
导读 日前,ThinkPad巨匠P系列专业移动工作站迎来全线更新,包括ThinkPad P1隐士2019.ThinkPad P53.ThinkPad P73.ThinkPad P43s.ThinkPa ...