医院设置 题解

医院设置

题目

设有一棵二叉树(如右图)。其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为1。如 右图中,若医院建在:
  1处,则距离和=4+12+220+240=136
  3处,则距离和=4*2+13+20+40=81
在这里插入图片描述


输入

第一行一个整数n,表示树的结点数。(nn<=100)
接下来的n行每行描述了一个结点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为0表示无链接;第三个数为右链接。


输出

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


样例

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

output
81


解题思路

SPFA
枚举每个点做起点
求出每个点到起点的最低距离
每个点的居民数 * 每个点到起点的最低距离,累加求出最小距离和


代码

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,t,x,y,mi=0x7fffffff,b[10020],f[10200],p[12000],d[10020],head[10200];
struct c{
	int x,next;
}a[12000];
void demo(int i){
	memset(p,0,sizeof(p));
	memset(d,0x7f,sizeof(d));
	memset(f,0,sizeof(f));  
	p[i]=1;
	f[1]=i;
	d[i]=0;
	int h=0,t=1;
	do{
		h++;
		for (int j=head[f[h]];j;j=a[j].next)
		    if (d[f[h]]+1<d[a[j].x])  //松弛操作
		    {
		    	d[a[j].x]=d[f[h]]+1;
		    	if (p[a[j].x]==0)  //未进入队列
		    	{
		    		t++;
		    		f[t]=a[j].x;
		    		p[a[j].x]=1;
		    	}
		    }
		p[f[h]]=0; 
	}while (h<t);
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d%d",&b[i],&x,&y);
		if (x!=0)
		{
		   t++;
		   a[t].x=x;
		   a[t].next=head[i];
		   head[i]=t;
		   t++;
		   a[t].x=i;
		   a[t].next=head[x];
		   head[x]=t;
	    }
	    if (y!=0)
	    {
		   t++;
		   a[t].x=y;
		   a[t].next=head[i];
		   head[i]=t;
		   t++;
		   a[t].x=i;
		   a[t].next=head[y];
		   head[y]=t;
	    }
	}  //构建邻接表,无向图,若x,y为0不用存
	for (int i=1;i<=n;i++)
	{
		int ans=0;
		demo(i);  //枚举每个点做起点
		for (int j=1;j<=n;j++)
		    ans+=b[j]*d[j];  //求距离和
		mi=min(ans,mi);
	}
	cout<<mi<<endl;
	return 0;
}
发布了34 篇原创文章 · 获赞 7 · 访问量 616
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览