公司聚会

Stewart教授是一家公司总裁的顾问,这家公司计划一个公司聚会。这个公司有一个层次式的结构;也就是说,管理关系形成一棵以总裁为根的树。人事部给每个雇员以喜欢聚会的程度来排名,这是个实数。为了使每个参加者都喜欢这个聚会,总裁不希望一个雇员和他(她)的直接上司同时参加。

Stewart教授面对一棵描述公司结构的树,使用了左子女、右兄弟表示法。树中每个结点除了包含指针,还包含雇员的名字和该雇员喜欢聚会的排名。描述一个算法,它生成一张客人列表,使得客人喜欢聚会的程度的总和最大。分析你的算法的执行时间。

分析:求出以每个节点为根节点的子树去或者不去的最大喜欢程度和,以此往上推,本题就是求根节点去或者不去的最大喜欢程度。显然,这具有最优子序列结构。给每个节点增加两个域,select,unsel,select[i]表示i节点去时,以i节点为根的子树的喜欢程度和,unsel[i]表示i节点不去时,所获得的喜欢程度和。

公式如下:

r.select=r.data+sum(unsel[j]);//j为r的孩子,r.data为节点r的喜欢程度

r.unsel=sum(max{unsel[j],select[j]});

当i选择去时,它的孩子节点肯定不能去;当i不去时,其孩子节点可以选择去或者不去;然后根据求出的根节点的最大喜欢程度和,找出参加的名单。首先是计算每个节点为根的子树的最大喜欢程度和。

参考链接:http://blog.sina.com.cn/s/blog_628e4b6901016gzu.html

// gongsujuhui.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<stack>
#include<queue>
using namespace std;

typedef struct TreeNode *Position;
typedef struct TreeNode *Tree;

struct TreeNode {
	int love;//喜欢聚会的程度
	Position parent, leftChild, rsibling;
	int select, unselect;        //去或不去以该节点为根的子树的喜欢程度
	bool go;
};

Tree initTree(int love[],int n)             //初始化公司树,15个节点的二叉树,n是人数,love是喜欢程度
{
	Tree T = (Tree)malloc(sizeof(TreeNode));
	T->love = love[1];
	T->parent = NULL;
	T->rsibling = NULL;
	T->go = true;
	T->select = 0;
	T->unselect = 0;
	queue<Position> que;
	que.push(T);
	for (int i = 2; i <= n; i+=2)
	{
		Position pLeft = (Position)malloc(sizeof(TreeNode));
		Position pRight = (Position)malloc(sizeof(TreeNode));
		que.front()->leftChild = pLeft;
		pLeft->love = love[i];
		pRight->love = love[i + 1];
		pLeft->parent = pRight->parent=que.front();
		que.pop();
		pLeft->rsibling = pRight;
		pLeft->leftChild = NULL;
		pRight->leftChild = NULL;
		pRight->rsibling = NULL;
		pLeft->go = pRight->go = true;
		pLeft->select = pLeft->unselect = pRight->select = pRight->unselect = 0;
		que.push(pLeft);
		que.push(pRight);
	}
	return T;
}

void print(Tree T)               //打印公司树
{
	Position left, right;
	queue<Position> que;
	que.push(T);
	while (!que.empty())
	{
		if(que.front()->go)cout << que.front()->love<<‘\t‘;
		left = que.front()->leftChild;
		que.pop();
		if (left != NULL)
		{
			right = left->rsibling;
			que.push(left);
			if (right != NULL)
			{
				que.push(right);
			}

		}
	}
	cout << endl;
}

int sumUnselectSon(Position p)
{
	Position left = p->leftChild;
	int sum = left->unselect;
	while (left->rsibling!=NULL)
	{
		left = left->rsibling;
		sum += left->unselect;
	}
	return sum;
}

int sumMaxson(Position p)
{
	Position left = p->leftChild;
	int sum = left->select > left->unselect ? left->select : left->unselect;
	while (left->rsibling != NULL)
	{
		left = left->rsibling;
		sum += left->select > left->unselect ? left->select : left->unselect;
	}
	return sum;
}

void peopleSelect(Tree T)
{
	stack<Position> sta;
	Position p ;
	p = T;
	while (!sta.empty()||p!=NULL)
	{
		if(p!=NULL)
		{
		sta.push(p);
		while (p->leftChild!=NULL)
		{
			p = p->leftChild;
			sta.push(p);
		}
		}
		p=sta.top();
		sta.pop();

		if (p->leftChild == NULL)
		{
			p->select = p->love;
			p->unselect = 0;
		}
		else
		{
			p->select = p->love + sumUnselectSon(p);
			p->unselect = sumMaxson(p);
		}

		p = p->rsibling;
	}
}

void PeopleList(Tree T)
{
	Position r, s;
	r = T;
	if (r == NULL) return;
	else if (r->parent == NULL) {
		if (r->select > r->unselect)
			r->go = 1;
		else
			r->go = 0;
	}
	else
	{
		if (r->parent->go)
			r->go = false;
		else {
			if(r->select > r->unselect)
				r->go = 1;
			else
				r->go = 0;
		}
	}
	if (r->leftChild)
	{
		r = r->leftChild;
		s = r->rsibling;
		PeopleList(r);
		PeopleList(s);
	}
}
int main()
{
	int love[] = { 0,2,5,3,4,8,6,7,17,9,10,16,12,8,3,15 };
	Tree T = initTree(love, 15);
	print(T);
	peopleSelect(T);
	PeopleList(T);
	print(T);
	while (1);
    return 0;
}

  

时间: 2024-08-10 02:11:05

公司聚会的相关文章

HDU 1520 树形dp裸题

1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using nam

北京簋街 美食全然攻略 + 簋街好吃的夜宵去处-----店铺介绍大全

作者:lihao102 为什么叫簋街? 簋街东起二环路东直门立交桥西端,西到交道口东大街东端.在这条全长1442米的东内大街上,沿街共同拥有各种商业店铺150多家,当中餐饮服务业100多家,约占东内大街所有店铺的60%以上.饭馆密度如此之大,全北京恐怕再也找不出第二条来了.至于簋街名字的由来,据说是来自老北京的“鬼市”.早年北京那些以贩卖杂货菜果为主的集市,后半夜开市,黎明即散,摊主以煤油灯取亮,远处看上去灯影憧憧,故名“鬼市”.另一种通常的说法是东直门内大街餐厅生意红火,因为来此宵夜的出租汽车

最近那些事儿……

为了不耽误大家的时间,这里首先说一下下边文章中主要涉及的技术问题,如果有兴趣,大家可以一起研究一下,如果不喜欢,请绕道.写得不妥的地方,也希望大家指正. 本文主要说三个问题: 一.VS中跨工程调试,从一个工程进入另一个工程: 二.动态生成二维码和一维条形码: 三.前台页面直接访问图片流文件. 老规矩,先来点题外话.最近在园子里闲逛的时候,发现很多人都聊到了加班这个话题.其中有一哥们儿说是在京东,然后每天按时上下班,无不良记录,一个月后居然以工作不积极给开了--说到这里很多人就得有想法了,凭什么啊

AutoMapper使用手册(一)

阅读目录 1. 介绍 2. 基本使用 3. 自动分割映射(Flattening) 4. 自定义字段映射(Projection) 5. 验证配置(Configuration validation) 介绍 AutoMapper是一个轻量级的类库,主要功能是把一个对象转换成另外一个对象,而避免我们每次都手工去转换. 常见几种使用场景: 对外服务接口,把逻辑层的实体转换成服务消费者需要的字段. UI展现层,把业务对象转换成UI需要展现的字段. 用户的输入输出,把DTO与领域模型互转. AutoMappe

在CSDN上看见一个程序猿的随笔,感触挺深的转发一下

[聊一聊]程序猿的恶心循环 穷人的恶性循环:穷 -> 需要努力工作 -> 没有时间去交际 -> 人脉越来越狭窄 -> 工作越来越难做 -> 越需要努力去工作 -> 越没有时间去发展人脉 -> 越穷富人的良性循环:有钱 -> 工作很轻松 -> 很多时间都在交际上 -> 人脉越来越广 -> 工作越来越不用努力 -> 越有更多的时间精力去发展人脉 -> 越富有 程序员的恶性循环:加班 -> 没空学习 -> 老是写同等水平代

动态规划总结与思考

动态规划 & 思索 1 首先要先分析问题的结构,也记得自顶向下的去考虑一个问题,使用自顶向下的想法是在尝试着使用递归的方法,递归的过程中就会出现子问题,然后我们在去分析如果直接使用分治的方法的时间复杂性是多少,如果是指数级别的,那么我们就要进行第二步的思索. 2 这些自问题是否是独立的,如果不是独立的,那么自问题的个数是否是有多项式级别的,如果这个问题的子问题之间有交叉,而且子问题的个数是有限的,那么请进入第三步的思考方式? 3 子问题之间是否可以互相依赖,比如最优性的依赖,如果一个问题是的解是

毕业一年之2013.6-2014.6

2013年6月9号,拿到学历证和学位证,我毕业了.2013年6月11号,我和王倩携着大包小包踏上了开往北京城的T98.由于只提前了一天买票,没有座位,一路站了5个小时于下午3点到达北京.刚下火车就下雨了,那个时刻我心中对北京也是有些许的惊喜吧.(因为2010年暑假来过一次,玩了7天,北京留给我的印象就是宽阔洁净的马路,楼很高,挺好的,比郑州好多了)  惊喜只是一点点,更多的是无助感.因为我们俩面对的第一个问题是晚上住哪,当时带了2000块钱,还要支撑到在北京找到工作,也不知道自己什么时候能找到工

偷车贼遭车主3小时轰炸归车 车钥匙丢失更加简单易寻

据外媒报道,美国一名窃贼日前盗走一辆小货车,不料车主的手机也在小货车上,窃贼遭到了失主的3小时“短信”轰炸.失主在短信中指责窃贼偷去了5个孩子的母亲赖以维生的货车,毁了她的生活:失主也不忘正面引导窃贼,她也向窃贼表示,归还汽车会是天大的恩典.最终车主终于回复认错,还说明自己偷车也是为了养家糊口,并且偷车贼还指示失主如何取得丢失的车辆. 丢失车钥匙这看起来很少发生的事情,但在我们身边却还是有很粗心的车主经常丢失车钥匙.当您开车在外不小心丢失了钥匙,一定不要慌不要急,因为车钥匙丢失是有很多方法去解决

AutoMapper搬运工之自定义映射

回顾 上节说到了AutoMapper的简单使用,对于复杂的Mapping需要强大的自定义,这节我们来看下AutoMapper的自定义Mapping(Projection) 搬运自Git:https://github.com/AutoMapper/AutoMapper/wiki/Projection 实例 本篇的场景是一个简单的日历事件,我们首先定义一个日历的事件如下: 1 public class CalendarEvent 2 { 3 //事件日期 4 public DateTime Date