網(wǎng)站開發(fā)dreamweaver站長工具ip地址查詢
題目描述
設(shè)有一棵二叉樹,如圖:
其中,圈中的數(shù)字表示結(jié)點(diǎn)中居民的人口。圈邊上數(shù)字表示結(jié)點(diǎn)編號(hào),現(xiàn)在要求在某個(gè)結(jié)點(diǎn)上建立一個(gè)醫(yī)院,使所有居民所走的路程之和為最小,同時(shí)約定,相鄰接點(diǎn)之間的距離為?11。如上圖中,若醫(yī)院建在?11?處,則距離和?=4+12+2×20+2×40=136;若醫(yī)院建在?3?處,則距離和=4×2+13+20+40=81。
輸入格式
第一行一個(gè)整數(shù)?n,表示樹的結(jié)點(diǎn)數(shù)。
接下來的?n?行每行描述了一個(gè)結(jié)點(diǎn)的狀況,包含三個(gè)整數(shù) w,u,v,其中?w?為居民人口數(shù),u?為左鏈接(為?0?表示無鏈接),v?為右鏈接(為0?表示無鏈接)。
輸出格式
一個(gè)整數(shù),表示最小距離和。
輸入輸出樣例
輸入 #1
5 13 2 3 4 0 0 12 4 5 20 0 0 40 0 0
輸出 #1
81
說明/提示
數(shù)據(jù)規(guī)模與約定
對(duì)于?100%的數(shù)據(jù),保證 1≤n≤100,0≤u,v≤n,1≤w≤10^5。
?解題思路
本題求距離和最短,可以用廣搜,首先一重循環(huán)遍歷以不同點(diǎn)為終點(diǎn),再嵌套一重循環(huán),遍歷每一個(gè)起點(diǎn),求所以起點(diǎn)到終點(diǎn)的距離之和,每次更新最小值,我們知道二叉樹的每個(gè)結(jié)點(diǎn)有三個(gè)去向父節(jié)點(diǎn),左孩子,右孩子,題目已經(jīng)要求輸入每個(gè)點(diǎn)的左右孩子,所以只要求出每個(gè)點(diǎn)的父節(jié)點(diǎn)就行了,具體操作看代碼。
#include<stdio.h>
struct nb {//2叉樹結(jié)點(diǎn)int data;//每個(gè)結(jié)點(diǎn)的人數(shù)int f;//父節(jié)點(diǎn)int lchild, rchild;//左右孩子
}a[110];
struct nm {//列隊(duì)用于廣搜int x;//編號(hào)int s;//步數(shù)
}b[100100];
int n, book[110];//book數(shù)組用于標(biāo)記
void dfs(int x,int y)//求父節(jié)點(diǎn) x為編號(hào),y為父節(jié)點(diǎn)
{if (x == 0)//沒有孩子,結(jié)束遞歸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(i=1;i<=n;i++)//scanf("%d %d %d", &a[i].data, &a[i].lchild, &a[i].rchild);dfs(1, 0);//從根結(jié)點(diǎn)開始for (i = 1; i <= n; i++)//分別以每一個(gè)點(diǎn)為終點(diǎn){int sum = 0;for (j = 1; j <= n; j++)//遍歷每一個(gè)起點(diǎn){if (i == j)//起點(diǎn)終點(diǎn)重合直接跳過continue;for (int q = 1; q <= n; q++)//初始化標(biāo)記數(shù)組book[q] = 0;//列隊(duì)插入起點(diǎn)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++)//往三個(gè)方向走,父節(jié)點(diǎn),左孩子,右孩子{int t;if (q == 1)t = a[b[hard].x].f;//往父節(jié)點(diǎn)走else if (q == 2)t = a[b[hard].x].lchild;//往左孩子elset = a[b[hard].x].rchild;//往右孩子if (t == 0)//沒有子節(jié)點(diǎn)或父節(jié)點(diǎn)continue;if (book[t] == 0)//如果第一次來這個(gè)點(diǎn){//入隊(duì)操作b[tail].x = t; book[t] = 1;b[tail].s = b[hard].s + 1; tail++;if (t == i)//如果找到終點(diǎn){flag = 1;break;}}}if (flag == 1){sum += a[j].data * b[tail - 1].s;//計(jì)算路程break;}hard++;}}if (min > sum)//更新最小值min = sum;}printf("%d", min);//打印結(jié)果return 0;
}