2012年网站设计方法,免费简约ppt模板,珠海网站开发维护科技公司,wordpress 发布vr题目描述
设有一棵二叉树#xff0c;如图#xff1a; 其中#xff0c;圈中的数字表示结点中居民的人口。圈边上数字表示结点编号#xff0c;现在要求在某个结点上建立一个医院#xff0c;使所有居民所走的路程之和为最小#xff0c;同时约定#xff0c;相邻接点之间的距…题目描述
设有一棵二叉树如图 其中圈中的数字表示结点中居民的人口。圈边上数字表示结点编号现在要求在某个结点上建立一个医院使所有居民所走的路程之和为最小同时约定相邻接点之间的距离为 11。如上图中若医院建在 11 处则距离和 4122×202×40136若医院建在 3 处则距离和4×213204081。
输入格式
第一行一个整数 n表示树的结点数。
接下来的 n 行每行描述了一个结点的状况包含三个整数 w,u,v其中 w 为居民人口数u 为左链接为 0 表示无链接v 为右链接为0 表示无链接。
输出格式
一个整数表示最小距离和。
输入输出样例
输入 #1
5
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0输出 #1
81
说明/提示
数据规模与约定
对于 100%的数据保证 1≤n≤1000≤u,v≤n1≤w≤10^5。 解题思路
本题求距离和最短可以用广搜首先一重循环遍历以不同点为终点再嵌套一重循环遍历每一个起点求所以起点到终点的距离之和每次更新最小值我们知道二叉树的每个结点有三个去向父节点左孩子右孩子题目已经要求输入每个点的左右孩子所以只要求出每个点的父节点就行了具体操作看代码。
#includestdio.h
struct nb {//2叉树结点int data;//每个结点的人数int f;//父节点int lchild, rchild;//左右孩子
}a[110];
struct nm {//列队用于广搜int x;//编号int s;//步数
}b[100100];
int n, book[110];//book数组用于标记
void dfs(int x,int y)//求父节点 x为编号y为父节点
{if (x 0)//没有孩子结束递归return;a[x].f y;dfs(a[x].lchild, x);//往左孩子走dfs(a[x].rchild, x);//往右孩子走return;
}
int main()
{int i, j, min 1e9;scanf(%d, n);for(i1;in;i)//scanf(%d %d %d, a[i].data, a[i].lchild, a[i].rchild);dfs(1, 0);//从根结点开始for (i 1; i n; i)//分别以每一个点为终点{int sum 0;for (j 1; j n; j)//遍历每一个起点{if (i j)//起点终点重合直接跳过continue;for (int q 1; q n; q)//初始化标记数组book[q] 0;//列队插入起点int hard 1, tail 1, flag 0;b[tail].x j; b[tail].s 0;book[j] 1; tail;while (hard tail){for (int q 1; q 3; q)//往三个方向走父节点左孩子右孩子{int t;if (q 1)t a[b[hard].x].f;//往父节点走else if (q 2)t a[b[hard].x].lchild;//往左孩子elset a[b[hard].x].rchild;//往右孩子if (t 0)//没有子节点或父节点continue;if (book[t] 0)//如果第一次来这个点{//入队操作b[tail].x t; book[t] 1;b[tail].s b[hard].s 1; tail;if (t i)//如果找到终点{flag 1;break;}}}if (flag 1){sum a[j].data * b[tail - 1].s;//计算路程break;}hard;}}if (min sum)//更新最小值min sum;}printf(%d, min);//打印结果return 0;
}