题目描述
Dear contestant, I bet you must know what a tree represent. In data structure, we learn a tree is a graph in which every two nodes have and only have one path.
Here comes an easy problem, given a tree with nodes have its weight, the weight of a tree is the sum of the weight of all nodes on it. Now we have a chance to divide the tree into two subtrees, and we want to know the minimum difference between the two subtrees'weight.
Input
The first line contains a single integer T, indicating the number of test cases.
Each test case begins with one integer N (2 <= N <= 10000), indicating the number of tree's nodes. Then N integers Wi (1 <= Wi <= 1000) follow, indicating the weight of nodes from 1 to N.
Then N-1 lines follow, each line contains two integers Ai and Bi (1 <= Ai, Bi <= N), indicating one edge of the tree.
Output
For each test case, output one integer, indicating the minimum weight difference.
Sample Input
2
2
1 2
1 2
4
1 2 1 2
1 2
1 3
1 4
Sample Output
1
2
这道题是一道简单的DFS,开始以为它是一棵有向的树,就wa了,后来看了解题报告发现它是无向的。现在越来越发现vector<>太强大了。
算法看看代码就知道了
代码:
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
vector<int>tree[10005];
int node[10005];
int son[10005];
int n,cnt;
void dfs(int x,int p)
{
int i;
son[x]=node[x];
for(i=0;i<tree[x].size();i++)
{
if(tree[x][i]!=p)
{
dfs(tree[x][i],x);
son[x]+=son[tree[x][i]];
}
}
}
int main()
{
int i,j,t,a,b,min,c;
freopen("g.in","r",stdin);
freopen("out.txt","w",stdout);
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
cnt=0;
memset(son,0,sizeof(son));
for(i=0;i<=n;i++) tree[i].clear();
for(i=1;i<=n;i++)
{
scanf("%d",&node[i]);
cnt+=node[i];
}
for(i=0;i<n-1;i++)
{
scanf("%d%d",&a,&b);
tree[a].push_back(b);
tree[b].push_back(a);
}
dfs(1,0);
min=0x7fffffff;
for(i=2;i<=n;i++)
{
c=abs(son[i]-(cnt-son[i]));
if(c<min) min=c;
}
printf("%d\n",min);
}
return 0;
}