• 没有上司的舞会 洛谷P1352


    Description

    某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。


    Input

    第一行一个整数N。接下来N行,第i+1行表示i号职员的快乐指数Ri。接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。


    Output

    输出最大的快乐指数。


    Hint

    -128<=Ri<=127,1<=N<=6000


    Solution

    用邻接表存树,找到根结点,重点是两个状态转移方程:
    当root结点是选了的时候:
    r[root][1]=r[i][0]+r[root][1];

    当root结点没选的时候:
    r[root][0]=max(r[i][1]+r[root][0],r[root][0]+r[i][0]);

    最后取选root和不选root的最大值就行了。


    注意事项:
    1.状态转移外面套邻接表的循环,并且要递归地转移。
    2.Max里面就不要用max了容易卡着,?:挺好用的。
    3.关于状态转移方程,他没选的时候就是他自己加上他的儿子选了或者没选的最大值,他选了就是他自己加上他儿子没选。

    luoguAC代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #define maxn 50005
    using namespace std;
    int r[maxn][2],first[2*maxn+5],nextt[maxn*2+5],rd[maxn];
    int n,x,y,root;
    void init(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&r[i][1]);
    	}
    	for(int i=1;i<=n-1;i++){
    		scanf("%d%d",&x,&y);
    		rd[x]++;
    		nextt[x]=first[y];
    		first[y]=x;
    	}
    	for(int i=1;i<=n;i++){
    		if(!rd[i]){
    			root=i;
    			break;
    		}
    	}
    }
    int Max(int x,int y,int z){
    	int t=x>y?x:y;
    	return t>z?t:z;
    }
    int MMax(int x,int y,int z,int w){
    	int t=x>y?x:y;
    	int o=z>w?z:w;
    	return t>o?t:o;
    }
    void workk(int root){
    	for(int i=first[root];i;i=nextt[i]){
    		workk(i);
    		r[root][1]=Max(r[root][1],r[i][0]+r[root][1],r[i][0]);
    		r[root][0]=MMax(r[root][0],r[i][1]+r[root][0],r[i][1],r[i][0]);
    	}
    }
    int main(){
    	init();
    	workk(root);
    	printf("%d
    ",max(r[root][1],r[root][0]));
    	return 0;
    }
    

    CQYZoj上AC代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #define maxn 50005
    using namespace std;
    int r[maxn][2],first[2*maxn+5],nextt[maxn*2+5],rd[maxn];
    int n,x,y,root;
    void init(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&r[i][1]);
    	}
    	for(int i=1;i<=n-1;i++){
    		scanf("%d%d",&x,&y);
    		rd[x]++;
    		nextt[x]=first[y];
    		first[y]=x;
    	}
    	for(int i=1;i<=n;i++){
    		if(!rd[i]){
    			root=i;
    			break;
    		}
    	}
    }
    void workk(int root){
    	for(int i=first[root];i;i=nextt[i]){
    		workk(i);
    		r[root][1]=r[i][0]+r[root][1];
    		r[root][0]=max(r[i][1]+r[root][0],r[root][0]+r[i][0]);
    	}
    }
    int main(){
    	init();
    	workk(root);
    	printf("%d
    ",max(r[root][1],r[root][0]));
    	return 0;
    }
    
  • 相关阅读:
    Bozh 的技术博客 梦想成为Gnu/Linux | Unix后台架构师 | Read the fucking source code
    Welcome to the TANGO website
    repowatcher : about
    PyTango documentation — PyTango 8.0.2 documentation
    Visual Studio 2010旗舰版正式版序列号 civilman的专栏 博客频道 CSDN.NET
    BoostPro Binary Installer for Visual C++
    分享:httping 1.5.6 发布,HTTP 诊断工具
    浅析epoll – epoll函数深入讲解 C++爱好者博客
    分享:Jython动态加载Jar
    News BoostPro Computing BoostPro
  • 原文地址:https://www.cnblogs.com/virtual-north-Illya/p/10045318.html
Copyright © 2020-2023  润新知