zoukankan      html  css  js  c++  java
  • 公司聚会

       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不去时,其孩子节点可以选择去或者不去;然后根据求出的根节点的最大喜欢程度和,找出参加的名单。首先是计算每个节点为根的子树的最大喜欢程度和。
    // 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<<'	';
    		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;
    }
    

      

     
  • 相关阅读:
    HL7及PIX相关的测试工具
    HDU4570----Multi-bit Trie----简单的DP
    hdu2248
    poj 3693 Maximum repetition substring (后缀数组)
    高性能通道
    volyaire重振Infiniband
    利用iWARP/RDMA解决以太网高延迟
    linux 单网卡来绑定多IP实现多网段访问以及多网卡绑定单IP实现负载均衡
    C细节学习
    每2秒获取系统的赋值及内存使用率
  • 原文地址:https://www.cnblogs.com/linear/p/6657923.html
Copyright © 2011-2022 走看看