zoukankan      html  css  js  c++  java
  • 春节十二响「十二省联考2019」

    题意

    给定一颗树,要求将其上的节点分成若干组,使得每一组的节点互相不拥有祖先-后代关系。定义每一组的值为该组节点权值最大值,求值总和最小值。


    思路

    硬上不是很显然的贪心,但是数据中链的情况给了提示。

    考虑链的情况:

    对于根节点两侧的链,我们分别排序,然后覆盖选取即可。

    这个贪心的正确性是显然的。

    现在考虑完整的数据:

    对于每一个节点,维护一个大根堆,储存选取的权值。然后从底向上启发式合并,最后累加根节点的权值即可。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace StandardIO {
    
    	template<typename T>inline void read (T &x) {
    		x=0;T f=1;char c=getchar();
    		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
    		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
    		x*=f;
    	}
    
    	template<typename T>inline void write (T x) {
    		if (x<0) putchar('-'),x*=-1;
    		if (x>=10) write(x/10);
    		putchar(x%10+'0');
    	}
    
    }
    
    using namespace StandardIO;
    
    namespace Project {
    	#define int long long
    	
    	const int N=200200;
    	
    	int n,ans=0;
    	int cnt;
    	int head[N];
    	struct node {
    		int to,next;
    	} edge[N<<1];
    	int tim;
    	int a[N],fa[N],dfn[N],tmp[N];
    	priority_queue<int> Q[N];
    	
    	inline void add (int a,int b) {
    		edge[++cnt].to=b,edge[cnt].next=head[a],head[a]=cnt;
    	}
    	void dfs (int now) {
    		dfn[now]=++tim;
    		for (register int i=head[now]; i; i=edge[i].next) {
    			int to=edge[i].to;
    			dfs(to);
    			if (Q[dfn[now]].size()<Q[dfn[to]].size()) swap(dfn[now],dfn[to]);
    			int len=Q[dfn[to]].size();
    			for (register int j=1; j<=len; ++j) {
    				tmp[j]=max(Q[dfn[now]].top(),Q[dfn[to]].top());
    				Q[dfn[now]].pop(),Q[dfn[to]].pop();
    			}
    			for (register int j=1; j<=len; ++j) Q[dfn[now]].push(tmp[j]);
    		}
    		Q[dfn[now]].push(a[now]);
    	}
    	
    	inline void MAIN () {
    		read(n);
    		for (register int i=1; i<=n; ++i) read(a[i]);
    		for (register int i=2; i<=n; ++i) {
    			read(fa[i]);
    			add(fa[i],i);
    		}
    		dfs(1);
    		while (!Q[dfn[1]].empty()) ans+=Q[dfn[1]].top(),Q[dfn[1]].pop();
    		write(ans);
    	}
    	
    	#undef int
    }
    
    int main () {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	Project::MAIN();
    }
    
    
  • 相关阅读:
    方法重载与方法重写的概念和区别(转载)
    sql exist 和not exist(转载)
    SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思 sql server 2005 2008
    sql中的isnull
    sql中unique和distinct
    SQLServer中的Merge使用
    SQL Server系统表sysobjects介绍与使用
    sql select as
    存储过程SET XACT_ABORT ON
    SQL Server之存储过程基础知识
  • 原文地址:https://www.cnblogs.com/ilverene/p/11469357.html
Copyright © 2011-2022 走看看