#50-【Floyd】腐败分子看直播

版权声明:反正也没有人会转,下一个 https://blog.csdn.net/drtlstf/article/details/81237980

题目描述

随着里约奥运的开幕,在二高集训的腐败分子们悄悄有乐子了,他们常常围聚在某个人的电脑旁看奥运直播。但是,腐败分子的堕落性质决定了他们都不怎么想移动自己的位置,于是在谁的电脑上看直播成了腐败分子争吵的问题。

当然,腐败分子都是极其聪明的,他们马上把问题抽象为一个二叉树结构(如下图,其中圈中的数字表示腐败分子移动的艰难值,圈边上数字表示腐败分子的结点编号),他们把这个问题转换成在树上找一个点,使得所有人的移动艰难值最小。就下图而言,若在1处看直播,则各腐败分子的移动艰难值和=4+12+2*20+2*40=136;若在3处看直播,则移动艰难值和=4*2+13+20+40=81。(注意,相邻结点之间的距离为1。)显然,在3处看直播大家会更高兴。
 
现在,腐败分子们想知道他们最小的移动艰难值之和是多少,但是腐败分子的堕落性质决定了他们会把这个问题交给你解决,如果你解决不出来,他们就向Teacher Chen举报你腐败。

输入

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

输出

输出一个整数,表示最小的移动艰难值之和。

样例输入

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

样例输出

81

提示

分析

n<=100,数据还是很水的,Floyd算法可以通过。

#include <iostream>
#include <cstring>

#define SIZE 101

using namespace std;

int a[SIZE], dis[SIZE][SIZE];

int main(int argc, char** argv)
{
	int n, i, j, k, l, r, temp, res = 1e+09;
	
	memset(dis, 63, sizeof (dis));
	
	scanf("%d", &n);
	for (i = 1; i <= n; ++i)
	{
		dis[i][i] = 0;
		scanf("%d%d%d", &a[i], &l, &r);
		if (l) // 这就是一开始的图
		{
			dis[i][l] = dis[l][i] = 1; // 构建图
		}
		if (r)
		{
			dis[i][r] = dis[r][i] = 1;
		}
	}
	
	for (k = 1; k <= n; ++k) // 进行Floyd算法,找最短路
	{
		for (i = 1; i <= n; ++i)
		{
			for (j = 1; j <= n; ++j)
			{
				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
			}
		}
	}
	for (i = 1; i <= n; ++i)
	{
		temp = 0;
		for (j = 1; j <= n; ++j) // 求结果
		{
			temp += dis[i][j] * a[j];
		}
		res = min(res, temp);
	}
	
	printf("%d", res);
	
	return 0;
}

/*
这就是典型的设医院问题......
*/

猜你喜欢

转载自blog.csdn.net/drtlstf/article/details/81237980