题目描述: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的更多相关文章

  1. [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 ...

  2. [ACM]Link-Cut Tree实现动态树初探

    动态树问题是指的一类问题,而不是具体指的某一种数据结构.它主要维护一个包含若干有根树的森林,实现对森林的修改和查询等. 实现动态树的数据结构据说主要有4种,Link-Cut Tree是其中的一种.Li ...

  3. HDOJ-3065(AC自动机+每个模板串的出现次数)

    病毒侵袭持续中 HDOJ-3065 第一个需要注意的是树节点的个数也就是tree的第一维需要的空间是多少:模板串的个数*最长模板串的长度 一开始我的答案总时WA,原因是我的方法一开始不是这样做的,我是 ...

  4. HDOJ-2896(AC自动机+文本串中出现了哪几个模板串)

    病毒侵袭 HDOJ-2896 主要使用AC自动机解决,其次在query函数中改变一下,用来记录每个模板串出现的次数,还有insert函数中记录模板串的编号 需要注意最好使用结构体,而且不能一次性使用m ...

  5. 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 ...

  6. 九章算法系列(#3 Binary Tree & Divide Conquer)-课堂笔记

    前言 第一天的算法都还没有缓过来,直接就进入了第二天的算法学习.前一天一直在整理Binary Search的笔记,也没有提前预习一下,好在Binary Tree算是自己最熟的地方了吧(LeetCode ...

  7. [LeetCode] 系统刷题4_Binary Tree & Divide and Conquer

    参考[LeetCode] questions conlusion_InOrder, PreOrder, PostOrder traversal 可以对binary tree进行遍历. 此处说明Divi ...

  8. [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 ...

  9. Minimal Steiner Tree ACM

    上图论课的时候无意之间看到了这个,然后花了几天的时间学习了下,接下来做一个总结. 一般斯坦纳树问题是指(来自百度百科): 斯坦纳树问题是组合优化问题,与最小生成树相似,是最短网络的一种.最小生成树是在 ...

随机推荐

  1. 02-02Android 学习进度报告二

    今天我主要学习了Android的UI基础布局知识,主要是学习View与ViewGroup的概念以及其区别. 首先是代码说明: <?xml version="1.0" enco ...

  2. Prometheus简介【转】

    Prometheus简介 Prometheus受启发于Google的Brogmon监控系统(相似的Kubernetes是从Google的Brog系统演变而来),从2012年开始由前Google工程师在 ...

  3. GoJS简单示例

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. P3381 【模板】最小费用最大流(spfa板子)

    #include<bits/stdc++.h> using namespace std; #define lowbit(x) ((x)&(-x)) typedef long lon ...

  5. JavaScript之bind方法实现代码分析

    我们来分析一下bind方法的实现代码,下图的bind方法的实现为MDN(开发者社区)中的代码. 由上图可得:bind方法实现了两个功能:绑定this和科里化.

  6. 多实例mysql的安装和管理

    多实例mysql的安装和管理 http://blog.chinaunix.net/uid-20639775-id-3438560.html mysql的多实例有两种方式可以实现,两种方式各有利弊.第一 ...

  7. 最简单的mybatis增删改查样例

    最简单的mybatis增删改查样例 Book.java package com.bookstore.app; import java.io.Serializable; public class Boo ...

  8. CF 1198 A. MP3 模拟+滑动窗口

    A. MP3   题意:给你n个数,一个大小为8*I的容量,保存一个数需要多少容量取决于给定n个数的种类k,用公式 log2 k   计算,如果给定的容量不能保存所有数,选择减少数的种类来降低保存一个 ...

  9. 南邮平台之Hello,RE!

    小白闲逛了一下南邮平台看到了逆向这题,小白在网上看了一下别人的write up发现有点复杂.于是小白就试试看,直接Underfine然后结果就出来了.....有点意外...... 结果flag{Wel ...

  10. Java笔记--多线程

    1.线程的创建与运行(方式一): --1)创建一个Thread的子类: --2)重写Thread类的run()方法: --3)创建一个子类的对象: --4)调用线程的start()方法来启动线程,Ja ...