题目
图论中的树,是无向无环连通图。n个节点的树,有(n-1)条边。给定一棵树,每个节点都有一个权值。我们允许从这棵树中删掉一条边,把这棵树分成两棵树。每棵小树各自包含的节点的权值和定义为其自身的权值,我们的目标是,使得这两棵小树的权值差距尽可能小。(权值差的绝对值尽可能小。)
输入格式
多组数据,每组数据第一行是一个正整数n,表示树节点的个数(2<=n<=100000)。
第二行是n个空格分隔的正整数,表示每个节点的权值,该值不超过1000。
接下来有(n-1)行,每行有两个从1-n之间的整数,表示树的边。
输出格式
每组数据输出一行,表示最小的差距。
分析:
简单的想先构造出这个图,枚举办法,砍掉一条边,遍历两个连通图,求差即可。
代码:
#include <stdio.h>
#include <stdlib.h>
#define N 3
static int verticeValue[N] = {0};
static int graph[N][N] = {0};
static int result[N - 1] = {0};
static int index = 0;
static int branch_index = 0;
// 砍掉一边,两个分支权值之和
static int branch_result[2] = {0};
void createGraph()
{
int i = 0;
int tempX = 0, tempY = 0;
for (i = 0; i < N; i++)
{
scanf("%d", &verticeValue[i]);
}
for (i = 0; i < N - 1; i++)
{
scanf("%d", &tempX);
scanf("%d", &tempY);
graph[tempX - 1][tempY - 1] = 1;
graph[tempY - 1][tempX - 1] = 1;
}
}
int getFirstNeighbor(int i)
{
int col = 0;
if (i != -1)
{
for (; col < N; col++)
{
if (graph[i][col] == 1)
{
return col;
}
}
}
return -1;
}
int getNextNeighbor(int v, int w)
{
int col = 0;
if (v != -1 && w != -1)
{
for (col = w + 1; col < N; col++)
{
if (graph[v][col] == 1)
{
return col;
}
}
}
return -1;
}
void DFS(int i, int* visited)
{
visited[i] = 1;
branch_result[branch_index] += verticeValue[i];
int w = getFirstNeighbor(i);
while (w != -1)
{
if (visited[w] == 0)
{
DFS(w, visited);
w = getNextNeighbor(i, w);
}
else
{
return;
}
}
}
void getGap()
{
int i = 0;
int visited[N] = {0};
for (i = 0; i < N; i++)
{
if (visited[i] == 0)
{
DFS(i, visited);
branch_index++;
}
}
if (branch_result[1] - branch_result[0] > 0)
{
result[index] = branch_result[1] - branch_result[0];
}
else
{
result[index] = branch_result[0] - branch_result[1];
}
index++;
branch_index = 0;
branch_result[0] = 0;
branch_result[1] = 0;
return;
}
int getResult()
{
int x = 0, y = 0, i = 0, min = 0;
for (x = 0; x < N; x++)
{
for (y = 0; y < x + 1; y++)
{
if (graph[x][y] != 0)
{
graph[x][y] = 0;
graph[y][x] = 0;
getGap();
graph[x][y] = 1;
graph[y][x] = 1;
}
}
}
printf("result : \n");
min = result[0];
for (i = 0; i < N - 1; i++)
{
printf("%d\n", result[i]);
if (result[i] < min)
{
min = result[i];
}
}
return min;
}
int main()
{
int local_result = 0;
createGraph();
local_result = getResult();
printf("local result = %d\n", local_result);
return 0;
}