NOIP模拟43

  考场正解,可惜写挂了。
  考虑模拟。
  考虑如何最大化一个士兵的作用。
  一个士兵首先肯定是一次性走到叶子是最优的,不然会有没有必要的重复路径。
  先递归至叶子,然后回溯时将回溯到的节点设为\(lca\)。
  然后处理\(lca\)的儿子。
  非叶子节点会在向叶子走时就将其占领,所以答案在叶子结算。
  接下来所说的节点只考虑叶子。
  对于一个节点,有两种情况:
  1、从根新派一个兵来这里。
  2、让之前的士兵来这里。
  1的花费是\(lca\)的深度+这个节点到\(lca\)的距离==这个节点的深度。
  2的花费是上一个士兵现在的位置到\(lca\)的距离+这个节点到\(lca\)的距离。
  只用比较前者就可以决定。
  每次处理完一个叶子后将士兵的位置设为当前。
  时间复杂度:\(\Theta\)(n)(一遍\(DFS\))。

Code
#include<bits/stdc++.h>
using namespace std;
namespace STD
{
	#define rr register
	typedef long long ll;
	const int N=1e5+4;
	int n,lca,now;
	ll ans;
	struct son
	{
		int id,h;
		son(){}
		son(int id_,int h_){id=id_,h=h_;}
		bool operator<(const son b) const
		{
			return h<b.h;
		}
	};
	vector<son> to[N];
	int depth[N],fa[N];
	int h[N];
	bool leaf[N];
	int read()
	{
		rr int x_read=0,y_read=1;
		rr char c_read=getchar();
		while(c_read<'0'||c_read>'9')
		{
			if(c_read=='-') y_read=-1;
			c_read=getchar();
		}
		while(c_read<='9'&&c_read>='0')
		{
			x_read=(x_read<<3)+(x_read<<1)+(c_read^48);
			c_read=getchar();
		}
		return x_read*y_read;
	}
	void dfs(int &x)
	{
		h[x]=1;
		int temp=INT_MIN;
		for(int i=0;i<to[x].size();i++)
		{
			if(to[x][i].id==fa[x]) continue;
			fa[to[x][i].id]=x;
			depth[to[x][i].id]=depth[x]+1;
			dfs(to[x][i].id);
			temp=max(temp,h[to[x][i].id]);
			to[x][i].h=h[to[x][i].id];
		}
		if(temp!=INT_MIN)
			h[x]+=temp;
		else if(to[x].size()==1&&to[x][0].id==fa[x])
			leaf[x]=1;
	}
	void deal(int &x)
	{
		if(leaf[x])
		{
			if(!now)
				ans+=depth[x];
			else
			{
				if(depth[now]-depth[lca]>depth[lca])
					ans+=depth[x];
				else
					ans+=depth[now]-2*depth[lca]+depth[x];
			}
			now=x;
			return;
		}
		sort(to[x].begin(),to[x].end());
		for(int i=0;i<to[x].size();i++)
		{
			if(to[x][i].id==fa[x]) continue;
			deal(to[x][i].id);
			lca=x;
		}
	}
};
using namespace STD;
int main()
{
	n=read();
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read();
		to[u].emplace_back(son(v,0));
		to[v].emplace_back(son(u,0));
	}
	int root=1;
	dfs(root);
	deal(root);
	cout<<ans;
}
  注意的是在递归过程中要优先递归最大链长最小的子树。
上一篇:leetcode77. 组合python


下一篇:CSS3 pointer-events属性