P1364

医院设置

题目描述

设有一棵二叉树,如图:

其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为 \(1\)。如上图中,若医院建在1 处,则距离和 \(=4+12+2\times20+2\times40=136\);若医院建在 \(3\) 处,则距离和 \(=4\times2+13+20+40=81\)

输入格式

第一行一个整数 \(n\),表示树的结点数。

接下来的 \(n\) 行每行描述了一个结点的状况,包含三个整数 \(w, u, v\),其中 \(w\) 为居民人口数,\(u\) 为左链接(为 \(0\) 表示无链接),\(v\) 为右链接(为 \(0\) 表示无链接)。

输出格式

一个整数,表示最小距离和。

样例 #1

样例输入 #1

5						
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0

样例输出 #1

81

提示

数据规模与约定

对于 \(100\%\) 的数据,保证 \(1 \leq n \leq 100\)\(0 \leq u, v \leq n\)\(1 \leq w \leq 10^5\)


Solution 1:
首先用Floyd预处理任意两点间的最短距离
(注意细节:k在最外层枚举 只要满足!(ij&&ik&&j==k)即可)
再枚举医院所在的节点 更新最小值即可

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int dis[105][105];
int g[105],n;
signed main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=n;i++)
	{
		dis[i][i]=0;
		cin>>g[i];
		int x,y;
		cin>>x>>y;
		if(x)dis[i][x]=dis[x][i]=1;
		if(y)dis[i][y]=dis[y][i]=1;
	}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
		{
			if(i==k)continue;
			for(int j=1;j<=n;j++)
			{
				if(i==j||j==k)continue;
				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
			}
		}
	int minn=dis[0][0];
	for(int i=1;i<=n;i++)
	{
		int tot=0;
		for(int j=1;j<=n;j++)tot+=dis[j][i]*g[j];
		minn=min(minn,tot);
	}
	cout<<minn<<"\n";
	return 0;
}
posted @ 2023-01-05 17:45  PKU_IMCOMING  阅读(17)  评论(0)    收藏  举报